中文乱码的问题是一个普遍遇到的问题,由于中西方编码方式的不同,单字节编码的方式在多字节编码的中文环境下经常会遇到转码后显示成“?”的问题,并且由于UTF-8,GBK,GB2312的差异也会导致一些莫名其妙的中文乱码出现。计算机环境下对字符串传输或存储需要经过先编码(编成字节流)后解码(转成字符串)的过程,因此,这么多种编码方式的并存,在编码和解码的过程中造成的乱码情况就会非常多。开发人员或许会根据经验处理其中的某几种情况,现场或用户更是一筹莫展,有没有办法根据现象来快速分析出出错的原因呢?或者总结出其中的规律?
以下以字符串“中*旻”为例,列举出经过常见编码方式两两组合进行转换的情形:
序号 | 编码方式 | 编码后的字节码 | 解码方式 | 解码后显示 |
1 | UTF-8 | -28 -72 -83 42 -26 -105 -69 | UTF-8 | 中*旻 |
2 | UTF-8 | -28 -72 -83 42 -26 -105 -69 | GBK | 涓?*鏃? |
3 | UTF-8 | -28 -72 -83 42 -26 -105 -69 | GB2312 | 涓?*??? |
4 | UTF-8 | -28 -72 -83 42 -26 -105 -69 | ISO-8859-1 | ???*??? |
5 | GBK | -42 -48 42 -107 70 | UTF-8 | ??*?F |
6 | GBK | -42 -48 42 -107 70 | GBK | 中*旻 |
7 | GBK | -42 -48 42 -107 70 | GB2312 | 中*?F |
8 | GBK | -42 -48 42 -107 70 | ISO-8859-1 | ??*?F |
9 | GB2312 | -42 -48 42 63 | UTF-8 | ??*? |
10 | GB2312 | -42 -48 42 63 | GBK | 中*? |
11 | GB2312 | -42 -48 42 63 | GB2312 | 中*? |
12 | GB2312 | -42 -48 42 63 | ISO-8859-1 | ??*? |
13 | ISO-8859-1 | 63 42 63 | UTF-8 | ?*? |
14 | ISO-8859-1 | 63 42 63 | GBK | ?*? |
15 | ISO-8859-1 | 63 42 63 | GB2312 | ?*? |
16 | ISO-8859-1 | 63 42 63 | ISO-8859-1 | ?*? |
表面上看来情形众多,没有头绪,其实有规可循:
首先,从表中可以看出只有UTF-8、UTF-8和GBK、GBK之间互转是没有问题的,其他都或多或少存在问题;
其次,使用单字节编码方式的“ISO-8859-1”是不能够用于中文的编码或解码的,只要有其参与的转换,都会出现“?”,因此如果出现一个汉字变成一个问号的情形,可以断定是错误的使用了“ISO-8859-1”对汉字进行编码;
另外,由于UTF-8多使用三个字节来编码一个汉字,而GBK和GB2312使用两个字节,并且GB2312不能处理类似“旻”这样的生僻字,因此如果出现汉字变成没有问号的乱码或部分问号加汉字的情形,基本上可以断定是这三者之间的两两转换出了问题。
最后总结字符串的转换原则如下:
l UTF-8转UTF-8和GBK转GBK是没有问题的;
l GB2312和GBK、GB2312之间在没有类似“旻”这样的生僻字的情况下也是可以相互转换的;
l UTF-8和GBK、GB2312之间是不能够相互转换的。
转自 http://blog.csdn.net/xjdawu/archive/2009/02/13/3887076.aspx