`
hz_chenwenbiao
  • 浏览: 994607 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

GBK与UTF-8 转换乱码详解(转)

阅读更多
getBytes 的功能是将字符转换成字节数组, 
gbk.getBytes("GB2312") 用GB2312翻译成字节数组, 
new String(gbk.getBytes("GB2312"),"UTF-8"); 
把用GB2312翻译成字节数组,再用UTF-8翻译成字符串。 
兄弟你想下,这里有没有问题? 
这就是乱码的原因。 

下面再分析下你具体的问题: 
GB23121 -》ISO-8859 两个字节到一个字节 
反过来,再一个字节到两个字节,不会有问题, 
因为翻译时,个数不会多也不会少。 

再看GBK -》UTF-8 两个字节翻译的字节数组现在要用三个字节翻译 
就是说你 4个字节给人家 人家是一次要三个,出现什么情况? 
拿了三个 剩下一个不够,人家就自己去添加。 
你再翻译回来的时候就是 6个字节了,也说明为什么变成了三个字

提供一个转换方法:
public byte[] gbk2utf8(String chenese){
    char c[] = chenese.toCharArray();
            byte [] fullByte =new byte[3*c.length];
            for(int i=0; i<c.length; i++){
             int m = (int)c[i];
             String word = Integer.toBinaryString(m);
            // System.out.println(word);
             
             StringBuffer sb = new StringBuffer();
             int len = 16 - word.length();
             //补零
             for(int j=0; j<len; j++){
              sb.append("0");
             }
             sb.append(word);
             sb.insert(0, "1110");
             sb.insert(8, "10");
             sb.insert(16, "10");
             
//             System.out.println(sb.toString());
             
             String s1 = sb.substring(0, 8);          
             String s2 = sb.substring(8, 16);          
             String s3 = sb.substring(16);
             
             byte b0 = Integer.valueOf(s1, 2).byteValue();
             byte b1 = Integer.valueOf(s2, 2).byteValue();
             byte b2 = Integer.valueOf(s3, 2).byteValue();
             byte[] bf = new byte[3];
             bf[0] = b0;
             fullByte[i*3] = bf[0];
             bf[1] = b1;
             fullByte[i*3+1] = bf[1];
             bf[2] = b2;
             fullByte[i*3+2] = bf[2];
             
            }
            return fullByte;
    } 

 应该编码转换的时候丢失了字节,你没有发现你输入的是偶数个字的时候正常,奇数个的时候乱码,具体的字码长度我也不是很了解
String str1 = new String(str.getBytes("UTF-8"),"GBK");
System.out.println(str1.length());
String str2 = new String(str1.getBytes("GBK"),"UTF-8");
System.out.println(str2.length());); 打印出来的字符串长度就不一样的
UTF8每个汉字占用3个字节,这样在某些地方文字个数的计算就和GBK编码的不一样,UTF-8使用可变长度字节来储存 Unicode字符,例如ASCII字母继续使用1字节储存,重音文字、希腊字母或西里尔字母等使用2字节来储存,而常用的汉字就要使用3字节。辅助平面字符则使用4字节。 GB 18030标准采用单字节、双字节和四字节三种方式对字符编码。单字节部分使用0×00至0×7F码(对应于ASCII码的相应码)。双字节部分,首字节码从0×81至0×FE,尾字节码位分别是0×40至0×7E和0×80至0×FE。四字节部分采用GB/T 11383未采用的0×30到0×39作为对双字节编码扩充的后缀,这样扩充的四字节编码,其范围为0×81308130到0×FE39FE39。其中第一、三个字节编码码位均为0×81至0×FE,第二、四个字节编码码位均为0×30至0×39。
按照程序员的称呼,GB2312、GBK到GB18030都属于双字节字符集 (DBCS)。

 

载自:http://jlins.iteye.com/blog/574670

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics