java 中文字符串,utf-8编码为byte数组的计算过程

背景:

 对于编码解码的计算过程一直没有去研究过。以前也看了大神写的编码解码的文章,当时看了似懂非懂,没有仔细去品味,没去实践。正应了那句老话:纸上得来终觉浅,绝知此事要躬行。

 为什么有编码和解码?二什么时候会出现编码和解码?编码解码的算法是怎样的?

         推荐两篇文章

 

                        http://www.ibm.com/developerworks/cn/java/j-lo-chinesecoding/

                         http://blog.csdn.net/baixiaoshi/article/details/40786503

          已经回答的很好了,^^偷懒不写了。

基础知识:

unicode转换为utf-8编码的规则

 

Unicode         UTF-8

 

0000-007F      0xxxxxxx

 

0080-07FF     110xxxxx 10xxxxxx

 

0800-FFFF    1110xxxx 10xxxxxx 10xxxxxx

 

 如果字符对应编码值小于0x7F,则转换该为1byte,最高位为00x7F转换为二进制为111111,71。不会出现最高位为1,最高位为1肯定大于7F。),该字符对应的二进制替换X,不足7位前面高位加0

 

    编码值在008007FF字符,会转换为2个字节,并且第一个字节以110开头,第二个字节以10开头,字符对应的编码值转换为2进制后的数据,填充X。不足位数的高位加0

 

    编码值在0800FFFF字符,会转换为3个字节,并且第一个字节以1110开头,后面字节以10开头,字符对应的编码值转换为2进制后的数据,填充X。不足位数的高位加0

 

    也就是说大于07XX编码值的字符,转换为字节时,第一个字节中连续1的个数表示该字符对应字节的长度

计算过程

          

String name = "中";
char[] chars = name.toCharArray();
//使用utf-8编码字符集
Charset charset = Charset.forName("utf-8");
CharBuffer charBuffer = CharBuffer.allocate(chars.length);
charBuffer.put(chars);
charBuffer.flip();
//字符编码为字节数组
ByteBuffer byteBuffer = charset.encode(charBuffer);
byte[] charToBytes = byteBuffer.array();
System.out.println("chars.length:" + chars.length+";bytes.length:" + charToBytes.length);
byte[] bytes = name.getBytes("utf-8");

 

 

    运行后byte数组值,可通过debug查看

 
java 中文字符串,utf-8编码为byte数组的计算过程_第1张图片
 

   转换过程

“中”的unicode通过查unicode编码表可知为:4E2D(十六进制的数,附件是网上找的一个编码表),通过转换为二进制:100111000101101。4E2D落在了0800~ FFFF区间内,再依据前面转换规则填充x。

 

   填充过程:
java 中文字符串,utf-8编码为byte数组的计算过程_第2张图片

最后获得 11100100  10111000 10101101

 

二进制到byte的换算过程

 

根据1个字节占8位,换算为字节数组[224,184,173],这和程序运行结果[-28-72-83],对不上,脑袋当时就卡了。然后一想不对呀,javabyte的范围是-128127,手工算出来的是224,184,173这明显超出了byte数值的范围。又一想这都是按无符号数进行二进制转换为byte。查了下无符号数转换为有符号数的规则(也有说这是补码):最高位用来表示符号,其余按位取反再加1

 

            按位取反                 1

11100100--------------->10011011-------------> 10011100

 

 最高位为符号位不参与计算,剩下的二进制0011100转换为十进制为 28,加上符号为-28

同理

        10111000转换后的十进制为 :-72

        10101101转换后的十进制为:-83

 

          最终和程序运行结果一样。

 

 

你可能感兴趣的:(编码,解码)