zoukankan      html  css  js  c++  java
  • Java 中文字符串编码之GBK转UTF-8

    写过两篇关于编码的文章了,以为自己比较了解编码了呢?!

    结果今天又结结实实的上了一课。

    以前转来转去解决的问题终归还是简单的情形。即iso-8859-1转utf-8,或者iso-8859-1转gbk,gb2312之类。这种无损转换,一行代码就搞定。

    今天遇到了gbk转utf-8。无论怎么转,都是乱码。

    一、乱码的原因

    gbk的中文编码是一个汉字用【2】个字节表示,例如汉字“内部”的gbk编码16进制的显示为c4 da b2 bf

    utf-8的中文编码是一个汉字用【3】个字节表示,例如汉字“内部”的utf-8编码16进制的显示为e5 86 85 e9 83 a8

    很显然,gbk是无法直接转换成utf-8,少字节变为多字节,谁知道缺少的字节是什么啊?!

    二、转换的办法

    有办法实现“有损”转换吗?答案是肯定的。

    1.首先将gbk字符串getBytes()得到两个原始字节,转换成二进制字符流,共16位。

    2.根据UTF-8的汉字编码规则,首字节以1110开头,次字节以10开头,第3字节以10开头。在原始的2进制字符串中插入标志位。最终的长度从16--->16+4+2+2=24。

    3.转换完成,实际情况需要考虑更多因素,例如字符串是汉字和数字的混合体,需要识别处理数字。

    三、不要重复发明轮子

    这段代码测试可用还很好用,需要的可以参考。

     1 public static String getUTF8StringFromGBKString(String gbkStr) {  
     2         try {  
     3             return new String(getUTF8BytesFromGBKString(gbkStr), "UTF-8");  
     4         } catch (UnsupportedEncodingException e) {  
     5             throw new InternalError();  
     6         }  
     7     }  
     8       
     9     public static byte[] getUTF8BytesFromGBKString(String gbkStr) {  
    10         int n = gbkStr.length();  
    11         byte[] utfBytes = new byte[3 * n];  
    12         int k = 0;  
    13         for (int i = 0; i < n; i++) {  
    14             int m = gbkStr.charAt(i);  
    15             if (m < 128 && m >= 0) {  
    16                 utfBytes[k++] = (byte) m;  
    17                 continue;  
    18             }  
    19             utfBytes[k++] = (byte) (0xe0 | (m >> 12));  
    20             utfBytes[k++] = (byte) (0x80 | ((m >> 6) & 0x3f));  
    21             utfBytes[k++] = (byte) (0x80 | (m & 0x3f));  
    22         }  
    23         if (k < utfBytes.length) {  
    24             byte[] tmp = new byte[k];  
    25             System.arraycopy(utfBytes, 0, tmp, 0, k);  
    26             return tmp;  
    27         }  
    28         return utfBytes;  
    29     }  

    PS:有点儿对不住原作者,找了很多代码,一一测试,结果网页都关闭了,如果有大神认领,我一定补充链接,而且深表感谢。

  • 相关阅读:
    MongoDB数据查询详解
    MongoDB增加数据
    laravel安装初体验
    操作MongoDB
    MongoDB基本概念和安装配置
    tp5操作mongo
    c语言运算符优先级与while循环案例
    tp5下通过composer实现日志记录功能
    c语言中类型转换与赋值运算符、算术运算符、关系运算符、逻辑运算符。原码、反码、补码。小解。
    scanf使用与运算符
  • 原文地址:https://www.cnblogs.com/yoyotl/p/5979200.html
Copyright © 2011-2022 走看看