gbk转为utf8乱码分析

参考一下帖子:
http://tieba.baidu.com/f?kz=859774972
http://topic.csdn.net/u/20090822/14/7abb7acf-e7c3-4ecd-979d-c141cd55b452.html


"锟斤拷"的产生,根本愿意是因为符号的编码方式和解码方式不同,或者转化过程中,有一些符号,用Unicode没法表示造成的。
通俗点说,这就好像用密钥A,加密的信息,用密钥B解密了,当然得到的结果是混乱的、错误的。

下面详细阐述一个例子。

中文windows系统,默认采用GBK的编码方式,在GBK编码方式,汉字"郁闷"一词,对应的编码为十六进制的D3 F4 C3 C6,其中D3 F4对应"郁"字,C3 C6 对应"闷"字。如果对D3 F4 C3 C6采用GBK方式解码,就能正确的得到汉字"郁闷"。

现在假设windows系统认为D3 F4 C3 C6是UTF-8格式的编码,它要解码为GBK格式,显示出来,错误就此产生了。

-------------------------------------
UTF-8就是以8位为单元对unicode进行编码。从UCS-2(2字节的unicode字符集)到UTF-8的编码方式如下:

UCS-2编码(16进制)     UTF-8 字节流(二进制)
0000 - 007F           0xxxxxxx
0080 - 07FF           110xxxxx 10xxxxxx
0800 - FFFF           1110xxxx 10xxxxxx 10xxxxxx
--------------------------------------

由于系统认为D3 F4 C3 C6是UTF-8格式的编码,它就要先转换为unicode格式,然后用GBK编码表中对应编码解码为汉字。
按照上面给出的UTF-8和unicode的转换规则反推。

1、先分析字节D3,D3的二进制表示为11010011,查看上表,以110开头的,必然是两个字节的UTF-8字符,从而要把D3 F4作为一个整体分析。

2、整体分析双字节 D3 F4, D3 F4的二进制表示为 110110011 11110100,查看上表,以110开头的,第二个字节的二进制开头必然是10,而F4 的二进制表示开头为11,所以D3 F4找不到UTF-8中对应的编码。

3、 由于无法匹配到正确的UTF-8码,于是舍弃D3,填充为UTF-8缺失字符EF BF BD, 即Unicode的占位符 U+FFFD, 符号?

4、依次分析 F4、C3、C6同样无法匹配到正确的UTF-8码,也被填充为EF BF BD

5、最终转换得到的字节流是 EF BF BD EF BF BD EF BF BD EF BF BD

6、在GBK编码表中,查找对应编码,并解码为汉字,由于EF BF 对应 锟,BD EF 对应 斤 BF BD 对应拷,从而得到"锟斤拷锟斤拷"

于是由于把GBK编码方式的字节流,用UTF-8方式进行解码,无法匹配,被转换为unicode占位符字节流,从而得到经典乱码"锟斤拷"。

你可能感兴趣的:(gbk转为utf8乱码分析)