Bootstrap

java编码处理_Java中的编码处理

感觉编码有三个部分组成:

生成字节数组的方法。

字节数组本身。

解析字节数组的方法。

一般情况下乱码的产生就是第三部分出错了,也就是用错误的方式解析字节数组。比如下面的例子:

public static void test_4(){

try{

String str1 = "我们";

String str2 = new String(str1.getBytes("UTF-8"), "GBK");

String str3 = new String(str2.getBytes("GBK"), "UTF-8");

System.out.println(str1);

System.out.println(str2);

System.out.println(str3);

print(str1.getBytes("UTF-8"));

print(str2.getBytes("GBK"));

print(str3.getBytes("UTF-8"));

}catch(Exception e){

}

}

输出:

----------------------------------------------------------------------------------

我们

鎴戜滑

我们

-26, -120, -111, -28, -69, -84,

-26, -120, -111, -28, -69, -84,

-26, -120, -111, -28, -69, -84,

但是这种来回的转换并不总是会成功,因为GBK表示一个汉字需要两个字节,而UTF-8则需要3个字节,这样如果是奇数个汉字的时候转换成的UTF-8就得对齐,然后再转回来当然就不一样了。通过这个例子也看到了方法getBytes和new String都做了些什么工作。

先来看ISO-8859-1编码,也就是这几天最闹心的一种编码。它是大多数浏览器的默认字符集,前128个字符对应ASCII字符集,后128个字符包含了一些被西欧国家使用的字符以及一些常用的特殊字符,是ASCII的超集。编码表如下:

e8702a699a853fd4c3d5d5abfcbb2763.gif

在网上捞到的一段从ISO-8859-1到UTF-8的转换的代码如下:

public static byte[] code8859toUTFNew(byte[] src){

byte [] dest = new byte[src.length*2 +1];

int i = 0, j = 0;

int value;

for(i =0; i < src.length;i++){

value = src[i]& 0xFF;

if (value <= 0x7F){

dest[j++] = src[i];

}else if(value >0x7F && value <= 0xFF){

dest[j++] = (byte)((value>>6)& 0x1F|0xC0);

dest[j++] = (byte)(value&0x3F|0x80);

}

}

byte [] end = new byte[j];

System.arraycopy(dest, 0, end, 0, j);

return end;

}

UTF-8编码:

UTF-8是一宗针对Unicode的可变长字符编码,也是一种前缀码,可用来表示Unicode标准中任何字符,且其编码中的第一个字节与ASCII相容。UTF-8的规则如下:

128个US-ASCII字符只需要一个字节编码(从U+0000到U+007F)。

带有符号的拉丁文,希腊文,西里尔字母,亚美尼亚语,希伯来文,阿拉伯文,叙利亚文与他拿字母需要两个字节编码(Unicode范围从U+0080到U+07FF)。

其他基于多文种平面中的字符使用三个字节编码。

其他极少使用的Unicode辅助平面的字符使用四个字节编码。

IETF要求所有的互联网协议都必须支持UTF-8编码。编码中的规则如下:

代码范围

UTF-8

注释

000000-00007F

0ZZZZZZZ

ASCII字符范围,字节由0开始

000080-0007FF

110YYYYY10ZZZZZZ

第一个字节110开始,接着的字节由10开始

000800-00D7FF

00E000-00FFFF

1110XXX10YYYYYY10ZZZZZZ

第一个字节由1110开始,接下来的字节由10开始

010000-10FFFF

11110WWW10XXXXXX10YYYYYY10ZZZZZZ

第一个字节由11110开始,接下来的由10开始

;