参考https://blog.csdn.net/chary8088/article/details/21226375,https://www.cnblogs.com/duanhuajian/p/3499697.html
js 字符串进行编码方法
escape是将字符的unicode编码转化为16进制序列(转义序列,转义序列(escape sequences)),其不编码字符有69个:*,+,-,.,/,@,_,0-9,a-z,A-Z。(不建议使用)
encodeURI是将字符的unicode编码通过UTF-8来表示,其不编码字符有82个:!,#,$,&,',(,),*,+,,,-,.,/,:,;,=,?,@,_,~,0-9,a-z,A-Z。
encodeURIComponent也是将字符的unicode编码通过UTF-8来表示,其与encodeURI的唯一区别就是它们不编码的字符有所差别,encodeURIComponent不编码的字符有71个:!, ',(,),*,-,.,_,~,0-9,a-z,A-Z。
16进制序列和utf-8之间的转换
<SPAN xmlns="http://www.w3.org/1999/xhtml">// #txt---
| Unicode符号范围 | UTF-8编码方式
n | (十六进制) | (二进制)
---+-----------------------+------------------------------------------------------
1 | 0000 0000 - 0000 007F | 0xxxxxxx
2 | 0000 0080 - 0000 07FF | 110xxxxx 10xxxxxx
3 | 0000 0800 - 0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
4 | 0001 0000 - 0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
5 | 0020 0000 - 03FF FFFF | 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
6 | 0400 0000 - 7FFF FFFF | 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
表 1. UTF-8的编码规则
// #txt---end
</SPAN>
已知"严"的unicode是4E25(1001110 00100101), 根据上表, 可以发现4E25处在第三行的
范围内(0000 0800 - 0000 FFFF), 因此"严"的UTF-8编码需要三个字节, 即格式是
"1110xxxx 10xxxxxx 10xxxxxx". 然后, 从"严"的最后一个二进制位开始, 依次从后向前
填入格式中的x, 多出的位补0. 这样就得到了, "严"的UTF-8编码是 "11100100 10111000
10100101", 转换成十六进制就是E4B8A5.
golang端编码和解码
编码:url.QueryEscape(str) 解码:url.QueryUnescape(str)
QueryEscape方法和js的encodeURI编码格式一致,都为utf-8;而url.QueryUnescape方法可以解码escape,encodeURI和encodeURIComponent方法。
如果js端对编码进行如下加密(使用escape)
function compileStr(code){ //对字符串进行加密
var c=String.fromCharCode(code.charCodeAt(0)+code.length);
for(var i=1;i<code.length;i++)
{
c+=String.fromCharCode(code.charCodeAt(i)+code.charCodeAt(i-1));
}
return escape(c); }
则golang端,则可以直接循环解密
func uncode(s string, sign int) string {
c := string(rune(int(s[0]) - len(s)))
for i := 1; i < len(s); i++ {
c += string(rune(int(s[i]) - int(c[i-1])))
}
return c
}
如果js端使用encodeURI(或golang端使用QueryEscape进行加密)则以上解密方式,QueryUnescape解密出则会乱码。。
经过排查,原因是for循环次数和加密循环次数不对应。(ASCII码值超过127的,len()长度都会大于1)
func uncompileStr(code string, sign int) (str string) {
str = string(rune(int([]rune(code)[0]) - sign))
for i := 1; i < len([]rune(code)); i++ {
str += string(rune(int([]rune(code)[i] - []rune(str)[i-1])))
}
return str
}