UTF-8
一、
1.Unicode
从AsciII表中获知 A = '65',即 在操作字符A时,计算机内部是对 (Unicode) 65进行操作
2.Java char <==> Unicode 标准字符集
int a = 'A'; System.out.println(a); // 将字符赋值给int类型数据,未报错,可以理解为 'A' 字符A指代的就是65
输出结果:65
3.UTF-8 表示 1~4字节变长
为何中文使用UTF-8编码为3字节?
3.1 输出汉字的二进制编码
Integer b = '中'; System.out.println(Integer.toBinaryString(b)); Integer c = '国'; System.out.println(Integer.toBinaryString(c));
输出结果:
100111000101101
101011011111101
3.2 编码
String d = "中" ; byte [] dArray = d.getBytes("UTF-8"); for(Integer index = 0 ; index < dArray.length; index ++){ System.out.println(Integer.toBinaryString(dArray[index] & 0xff)); } System.out.println(); String e = "国" ; byte [] eArray = e.getBytes("UTF-8"); for(Integer index = 0 ; index < eArray.length; index ++){ System.out.println(Integer.toBinaryString(eArray[index] & 0xff)); }
输出结果:
11100100
10111000
10101101
11100101
10011011
10111101
3.对比分析结果
1110_ _ _ _ 10_ _ _ _ _ _ 10_ _ _ _ _ _
中:100111000101101
(1110)0100 (10)111000 (10)101101
国:101011011111101
(1110)0101 (10)011011 (10)111101
即
通过3个字节来表示,
2~4*2~6*2~6=2~16
故汉字的Unicode的二进制为16位
101011011111101(长度16)
4.编码
// 结果:中 String h = new String(dArray,"UTF-8"); System.out.println(h); // 结果:乱码 String g = "国" ; byte [] gArray = g.getBytes("GBK"); for(Integer index = 0 ; index < gArray.length; index ++){ System.out.println(Integer.toBinaryString(gArray[index] & 0xff)); } String i = new String(gArray,"UTF-8"); System.out.println(i);
结论:
用什么格式解码用什么格式编码
5.java web 乱码
tomcat的自带编码是ISO-8859-1的格式
String j = new String(str.getBytes("ISO-8859-1"),"UTF-8"); System.out.println(j);
二、编码特点
1.
一种变长的编码方式。
用1~6个字节表示一个符号,根据不同的符号而变化字节长度。
Unicode编码长度是固定的,无论是数字、英文还是火星文。所以Unicode编码有点浪费空间。UTF8是针对unicode的空间浪费现象,它对字符的长度是动态的。
2.
UTF-8的编码规则很简单,只有二条:
1)对于单字节的符号,字节的第一位设为0,后面7位为这个符号的unicode码。因此对于英语字母,UTF-8编码和ASCII码是相同的。
2)对于n字节的符号(n>1),第一个字节的前n位都设为1,第n+1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的unicode码。
示例:如上
博文参考:
Java中字符编码问题和中文占几个字节的问题(ASCII Unicode UTF-8 )