Unicode字符集、UTF-8、UTF-16、UTF-32

1.Unicode字符集

Unicode(统一码、万国码、单一码)包括字符集、编码方案(UTF-8、UTF-16、UTF-32),它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。(末尾附unicode编码范围表)

2.UTF-8编码

变长编码,其特点如下

  1. 兼容 ASCII
  2. 没有字节序问题
  3. 以英文和西文符号比较多的场景下(例如 HTML/XML),编码较短
  4. 容错性高,局部的字节错误(丢失、增加、改变)不会导致连锁性的错误。
  5. 中日韩人民不得不忍受 3 字节 1 个字符。

Unicode到UTF-8的编码方式如下:

Unicode编码(十六进制) UTF-8 字节流(二进制)
000000-00007F 0xxxxxxx
000080-0007FF 110xxxxx 10xxxxxx
000800-00FFFF 1110xxxx 10xxxxxx 10xxxxxx
010000-10FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

在从utf-8解码成Unicode时,在尝试解析输入流时碰到了畸形的数据,单个字节会被替换为一个Unicode U+FFFD

3.UTF-32编码

定长编码,32位无符号表示一个字符,Unicode编码的二进制数就是其编码结果。特点

  1. 何字符都用 4 字节,索引较快。(找第几个字符时,不需要从头开始)
  2. 编解码方便,Unicode对应的32位二进制数就是其编码。
  3. 占用存储空间大
  4. 有字节序(BOM)问题

4.UTF-16

介于定长编码和变长编码之间,在0x0000 - 0xFFFF(BMP平面)区间,用两个字节表示,直接将Unicode转为16位二进制数就是其编码。当超出这个范围在编码时会将其拆分成两个unicode码(分别位于D800-DB7F和DC00 - DFFF),分别对应一个字符。
编码过程
(1)0x0000 - 0xFFFF(1个word)
直接将Unicode转为二进制,得到两个字节,就是其UTF-16编码。
(2)0x10000 - 0x10FFFF(2个word):
在这一区间内,需要拆分成一个位于D800-DB7F区间的高位替代码和一个位于DC00 - DFFF低位替代码,过程如下:
对Unicode码进行处理,U’ = U - 0x10000,U’对应二进制:yyyy yyyy yyxx xxxx xxxx。
分别得到两个处于BMP平面编码:110110yyyyyyyyyy(高位替代码)和110111xxxxxxxxxx(低位替代码),对应两个word.。
解码过程
每次读取两个字节,如果当前字符不属于高位替代码(D800-DB7F)范围,则为单字符,其二进制数对应的16进制数就是Unicode码。
反之当前字符位于高位替代码范围,读取下一字符,判断其是否属于低位代替码范围,如果是则两个字符解码为一个Unicod码。过程如下:
两个字符分别取其二进制后10位yyyyyyyyyy和xxxxxxxxxx得到U’ = yyyyyyyyyyxxxxxxxxxx,U = U’ + 0x10000。

特点

  1. 对于0000 - FFFF区间6万多字符,都用2个字节表示,简直中日韩福音(对于英文有点浪费)。
  2. 对于常用字节编码解码方便。(jvm内部对字符串就是UTF-16编码)
  3. 有字节序(BOM)问题

5.附

在这里插入图片描述

发布了28 篇原创文章 · 获赞 11 · 访问量 1537

猜你喜欢

转载自blog.csdn.net/weixin_42881755/article/details/100095605
今日推荐