java中文字符串编码_JAVA中文字符串编码--GBK转UTF-8

1、乱码的缘由html

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

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

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

转换的办法

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

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

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

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

public void entityTest(){

try {

byte[] str = "支持™".getBytes("gbk");

String gbkStr = new String(str, "gbk");

System.out.println(new String(getUTF8BytesFromGBKString(gbkStr),"UTF-8"));

} catch (UnsupportedEncodingException e) {

e.printStackTrace();

}

}

public static byte[] getUTF8BytesFromGBKString(String gbkStr) {

int n = gbkStr.length();

byte[] utfBytes = new byte[3 * n];

int k = 0;

for (int i = 0; i < n; i++) {

int m = gbkStr.charAt(i);

if (m < 128 && m >= 0) {

utfBytes[k++] = (byte) m;

continue;

}

utfBytes[k++] = (byte) (0xe0 | (m >> 12));

utfBytes[k++] = (byte) (0x80 | ((m >> 6) & 0x3f));

utfBytes[k++] = (byte) (0x80 | (m & 0x3f));

}

if (k < utfBytes.length) {

byte[] tmp = new byte[k];

System.arraycopy(utfBytes, 0, tmp, 0, k);

return tmp;

}

return utfBytes;

}

但在这里仍是有个问题是"支持™"字符串中"™"的字符因为在GBK中不存在,那么在byte[] str = "支持™".getBytes("gbk");的时候"™"字符就已经乱码了,最后致使转码也乱码。GBK还有不少不支持的特殊字符。it


版权声明:本文为weixin_36212175原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。