参考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
}