欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-07-14 20:52:45
...

背景:

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

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

         推荐两篇文章

 

                        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数组的计算过程
 

   转换过程

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

 

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

最后获得 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

 

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

 

 

相关标签: 编码 解码