Unicode与UTF-8
  nekASmZst2xT 2023年11月02日 30 0


软件开发中乱码问题经常遇到,Unicode,UTF-8, ASCII等都是高频词语,不过具体是啥意思其实都不清楚。这个周末研究了一下,略有了解,记录一下。

Unicode

Unicode本身是纯理论的东西,和具体计算机实现无关。它就是要给全世界的文字符号进行统一的编码。注意,是所有的文字符号,也就是除了正常的各国文字外,还包括包括了各式各样的符号,这样的话,理论上符号的数量是无上限的,虽然目前已经编码的符号还是有限的。

比如:英文字母

Unicode与UTF-8_十六进制

比如:汉字

Unicode与UTF-8_软件开发_02

比如:象棋相关

Unicode与UTF-8_Unicode_03

任何一个文字符号都有一个自己的编码,或者数字,称为“代码点(Code Point)”, 表示方法为:

U+XXXX

例如字母A的代码点是U+0041. 再次注意,目前为止这都是还是纯理论,和具体计算机无关。

按此,所有的字符及其Unicode编码构成的集合就叫Unicode字符集(Unicode Charactor Set, UCS)。

早期的版本有UCS-2, 用两个字节(BYTE)编码,最多能表示65535个字符。每个代码点的长度是16位。

后来UCS-2不够用了,因此出了UCS-4版本。UCS-4增加了两个字节,采用4个字节编码(最高位固定为0,因此实际用31位。UCS-4在结构上有一个分层关系,大致如下:

第一层:组(Group)

用最高字节分成 128组(最高字节的最高位固定为0,所以最高字节有128个)

第二层:平面(Plane)

对于每个组,再用次高字节分为256个平面

第三层:行(Row) / 码位(Cell)

对于每个平面,根据第三个字节分为256行,根据第四个字节分为256个码位。

总结如下图:

Unicode与UTF-8_ico_04

UCS-4中还有一些规定比如BMP,PUA之类的概念这里就不作记录了。

以上都是纯理论的部分,没有设计Unicode在计算机中的实现。需要注意的是,Unicode的实现方式和编码方式不一定等价。一个 字符的Unicode编码是确定 的,但在实际存储和传输过程中,不同的系统平台设计可能是不一致的,还有处于节省空间的目的 ,对Unicode编码的实现方式也可能不同。

UTF

Unicode编码的实现方式,称为Unicode转换格式(Unicode Transformation Format),简称UTF, 到这里,UTF这次词出现了,离日常接触的内容就比较近了。Unicode实现方式主要有UTF-8、UTF-16、UTF-32等,分别以不同的字节数作为编码单位:

UTF-8: 字节(BYTE,1个字节)

UTF-16: 字(WORD,2个字节)

UTF-16: 双字(DWORD, 4个 字节)

看到BYTE/WORD/DWORD这些 词,就能联想到一些具体的点了,例如注册表中的值,例如 C++中的数据类型。

UTF-8

下面记录一下UTF-8的具体实现:

UTF-8以字节为单位对Unicode进行编码,这里的单位是指程序在解析二进制流时的最小单元,在UTF-8中,程序是以一个字节一个字节地解析文本。UTF-8具体实现如下:

Unicde编码(Hex)所处范围

UTF-8字节流(Binary)

000000 ~ 00007F

0xxxxxxx

000080 ~ 0007FF

110xxxxx 10xxxxxx

000800 ~ 00FFFF

1110xxxx 10xxxxxx 10xxxxxx

010000 ~ 10FFFF

11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

从表格可以看出,UTF-8的特点是对不同范围的字符(也就是Unicode码点)使用不同长度的编码。

对于码点在0x00 ~ 0x7F的字符,UTF-8与ASCII编码相同。UTF-8编码的最大长度是4个字节,4字节模板有21个x, 也就是可以容纳21位二进制数。同时,Unicode的最大码点0x10FFFF也只有21位。

举例:中文字符 "电",怎样从Unicode实现为UTF-8?

查询得知,"电"的Unicde码是0x7535   (在线 Unicode 编码转换 | 菜鸟工具)

0x7535落在000800 ~  00FFFF这个范围 ,也就是表格 第三行,使用三字节模板:

1110xxxx 10xxxxxx 10xxxxxx

0x7535写成二进制是 0111010100110101, 根据模板分一下组就是:

0111  010100  110101, 填入模板:

11100111  10010100  10110101,写成十六进制就是:

E7 94 B5,用工具验证一下:

Unicode与UTF-8_软件开发_05

正确。

好了,Unicode与UTF-8的学习暂时告一段落。

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
  wURKzOHw9Irf   2023年12月24日   28   0   0 HTMLicoicohtml