接上一篇: 乱码问题及字符编码集(一)
下面我们用java语言对各种编码集对中文的编码和解码进行测试:
1. ASCII码:
String chineseStr = "哈哈";//原字符
byte[] ascii = chineseStr.getBytes("ASCII"); //解码
String asciiStr = new String(ascii, "ASCII");
System.out.println("使用ASCII编码显示中文" + asciiStr);
结果乱码了,如下: 可知ASCII码无法表示中文
使用ASCII编码显示中文??
2. GBK:
String englishStr = "hello world世界";//编码
byte[] ascii = englishStr.getBytes("ASCII");// 使用ASCII解码
System.out.println( "字节数:"+ ascii.length );
String gbkStr = new String(ascii, "GBK"); //重新用GBK编码
System.out.println("使用ASCII编码,使用GBK解码:" + gbkStr);
输出结果:
字节数:13
使用ASCII编码,使用GBK解码:hello world??
分析: 用ASCII解码时,中文也是当成一个字节输出,因为ASCII码中没有中文对应的码. 所以字节长为13, 这样再用 13个字节编码成GBK时,GBK对英文可以兼容,采用一个字节编码,不会乱码,但对中文再采用一个字节编码的话,就会出现乱码,因为中文需要多字节编码,而ASCII是单字节编码,由于ASCII无法识别多字节,所以进行了过滤,将所有的中文都过滤成了“?”. 这是常见的一种乱码情况。
3. Unicode:
String testStr = "abc哈哈하하あはは";//编码
byte[] unicode = testStr.getBytes("unicode");//解码
System.out.println( "字节数:"+ unicode.length );
String unicodeStr = new String(unicode, "unicode");
System.out.println("使用UNICODE编码和解码:" + unicodeStr);
输出结果:
字节数:22
使用UNICODE编码和解码:abc哈哈하하あはは
分析: unicode是定长编码,即通常情况用两个字节来表示,所以这里的 abc哈哈하하あはは 都是采用两个字节的,所以长度应该为20个字节,但请注意cpu在处理多字节时,有两种方式大端模式和小端模式, 它要增加多出的两个字节其实就是指定使用哪种存储模式,所以长度为 22个字节.
4.另一种情况: 中文成了看不懂的字符
String chineseStr = "哈哈";//编码
byte[] gbks = chineseStr.getBytes("GBK");//解码
System.out.println( "字节数:"+ gbks.length );
String gbksStr = new String(gbks,"ISO-8859-1");
System.out.println("使用GBK进行编码,使用ISO-8859-1进行解码"+gbksStr );
输出结果:
字节数:4
使用GBK进行编码,使用ISO-8859-1进行解码¹þ¹þ
分析: 编码和解码使用了两种不兼容的编码集,导致中文变成了其他语言符号