现在我们就来看看”朶”这个子是如何变成乱码的,经过对cjson源码的分析得知,cjson在处理字节流的时候当遇见’\’反斜杠时会猜测后一个字节应该是要被转义的字符,比如\b、\r之类的字符,如果是就放行,如果不是,cjson就认为这不是一个正确的json格式,就会把这个字节给干掉,所以本来用两个字节表示的汉子就硬生生的给掰弯了。
那”朶”字跟’\’反斜杠又有什么关系? 查询这两字符在编码中的表示得出:
“朶” 0x965C
“\” 0x5C
这样我们就看到”朶”字的低位字节和”\”字符相同,都是0x5C,如果这时候”朶”字后边不是b、r之类的可以被转移ascii字符,cjson就会把这个字节和紧跟其后的一个字节抹掉,所以乱码就产生了。
那我们应该怎么解决这个问题,让cjson可以顺利的支持gbk编码呢,首先我们看看gbk编码是怎么回事,为什么会出现低位字节和ascii冲突的问题.
GB_编码系列
先来了解一下GB系列的编码范围问题:
GB2312(1980)共收录7445个字符,6763个汉字和682个其他字符。
每个汉字及符号用两个字节表示,为了跟ascii兼容,处理程序使用EUC存储方法。
汉字的编码范围
高字节: 0xB0 – 0xF7,
低字节: 0xA1 – 0xFE,
占用72*94=6768,0xD7FA – 0xD7FE未使用。
GBK共收录21886个字符,采用一字节和双字节编码。
单字节表示范围
8位: 0x0 – 0x7F
双字节表示范围
高字节: 0x81 – 0xFE
低字节: 0x40 – 0x7E、0x80 – 0xFE
GB18030收录70244个汉字,采用1、2、4字节编码。
单字节范围
8位: 0x0 – 0x7F
双字节范围
高字节: 0x81 – 0xFE
低字节: 0x40 – 0xFE
四字节范围
第一字节:0x81 – 0xFE
第二字节:0x30 – 0x39
第三字节:0x81 – 0xFE
第四字节:0x30 – 0x39
由于GB类的编码都是向下兼容的,这里就有一个问题,因为GB2312的两个字节的高位都是1,符合这个条件的码位只有128*128=16384个。GBK和GB18030都大于这个数,所以为了兼容,我们从上面的编码范围看到,这两个编码都用到了低位字节的最高位可以为0的情况。
最终得出的结论就是,在GBK编码中只要该字符是两个字节表示,并且低位字节是0x5C的字符都会被cjson弄成乱码.
解决方案:
1) 不要使用gbk编码,将你的字符串转换成utf-8编码.
2) 对cjson源码稍微做个改动,就是在每个字节到来之前先判断该字节是否大于127,如果大于则将该字节个随后的一个字节放过,否则交给cjson去处理。
原创文章,转载请注明: 转载自 并发编程网 – ifeve.com
本文链接地址: JSON数据乱码问题
文章的脚注信息由WordPress的 wp-posturl插件 自动生成
JSON 乱码
作者:并发编程网 - ifeve.com
让天下没有难学的技术
原文地址:JSON数据乱码问题, 感谢原作者分享。
→《ZooKeeper官方指南》翻译邀请 ←《Apache Zookeeper官方文档》2-综述
发表评论