魔兽世界吧 关注:14,291,193贴子:460,754,149
  • 7回复贴,共1

【举例详细阐述经典乱码"锟斤拷"的产生】

取消只看楼主收藏回复

举例详细说明经典乱码"锟斤拷"。
"锟斤拷"的产生,根本愿意是因为符号的编码方式和解码方式不同,或者转化过程中,有一些符号,用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占位符字节流,从而得到经典乱码"锟斤拷"。



1楼2010-08-14 17:39回复
    不知道大家看懂了没有,写了半天,这东西太难阐述了。


    2楼2010-08-14 17:41
    回复
      广告
      立即查看
      可能还是理解起来有点困难,专业性有点强。


      3楼2010-08-14 17:42
      回复
        回复:4楼
        哪里没看懂?


        5楼2010-08-14 17:44
        回复
          编码的、字节序的东西,挺烦人的,乱呀。
          什么时候搞个统一的标准多好呀


          9楼2010-08-14 17:55
          回复
            回复:7楼
            这有什么用不用的?自己写程序时碰到乱码,不就知道是什么原因,什么错误了。
            要用的话,直接拷贝"锟斤拷"得了


            10楼2010-08-14 17:57
            回复
              锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷


              11楼2010-08-14 17:57
              回复
                就这么用的


                12楼2010-08-14 17:58
                回复