Unicode、UTF-8 编码原理

警告
本文最后更新于 2023-06-13,文中内容可能已过时。

之前我们聊到了 ASCII 编码,在 1960 年,美国人发明了 ASCII 编码,实现了英语以及数字的编码。但是这群老哥完全没考虑其他国家、其他语言的编码!所以各个国家地区陆续推出了他们自己的编码规范,出现了群雄割据的混乱局面,比如 ISO-8859-1 涵盖了大多数西欧语言字符,中国大陆的 GBK 编码等等。

因为编码规范的不同,研发人员在写代码时要考虑转码的情况,一不留神就会出现乱码!此外,计算机多次转码也会影响计算效率。为此,一个统一的编码规范是大家共同的夙愿,最终,Unicode 横空出世,一统江湖。

如果不了解“编码”这个概念请看:编码的作用是什么?常见的编码方式有哪些?

如果不了解 ASCII 编码请看:认识ASCII编码

下面我们详细聊聊 Unicode ~

认识 Unicode 码表

Unicode 为世界上所有字符都分配了一个唯一的数字编号,这个编号范围从 0x000000 到 0x10FFFF(十六进制),一共使用了 21 个bit,共有 1112064 个位置(111w)。

Unicode 规范规定,使用U+前缀加上一个 16 进制整数表示一个字符,比如U+0041表示A

Unicode 仅仅是提供了码表,至于具体的编码方式则有三种:UTF32、UTF16、UTF8。

UTF32 编码

Unicode 编码最大使用了 21 个 bit,需要 4 个字节才能装得下,所以 UTF-32 编码用四个字节表示 Unicode 字符。

UTF16

同理,UTF16 使用 2 个字节表示 Unicode 字符,如果 2 个字节不够用了,再扩展到 4 个字节,这种方式也叫“变长字节”:

  • 编号在U+0000U+FFFF的字符(常用字符集),用两个字节表示。
  • 编号在U+10000U+10FFFF的字符,用四个字节表示。

UTF8

同理,UTF-8 也是一种变长的编码方式。它可以使用 1~4 个字节表示一个 Unicode 字符。

UTF-8 的编码规则很简单,只有二条:

  1. 第一个字节的开头,有n1就代表占用n+1个字节。
  2. 其余的字节,以10开头。
  3. 每个字节的其他位,依次填入字符的二进制值。(下图中的x
字节数 用来填充二进制的位数 Unicode 十六进制码点范围 字节1 字节2 字节3 字节4
1 7 0000 0000 - 0000 007F 0xxxxxxx
2 11 0000 0080 - 0000 07FF 110xxxxx 10xxxxxx
3 16 0000 0800 - 0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
4 21 0001 0000 - 0010 FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

下面以汉字为例,演示 UTF-8 编码过程:

  1. “马”的 Unicode 编号是:0x9A6C
  2. 0x9A6C对应的二进制是 1001 1010 0110 1100,共需要 16 位,也就是需要 16 个x,对应上图的模板三,将二进制依次填入模板后得到结果:11101001 10101001 10101100。

总结

综合来看,UTF8 占用空间最小,这也是大家都推荐使用 UTF8 编码的原因,既能防止乱码,又能一定程度上节省空间。

另外,不知大家能否看出来 UTF8 对 ASCII 是兼容的,至于原因,就交给各位自己啦~

最后贴一个在线 Unicode 转码工具:https://tool.chinaz.com/tools/unicode.aspx


更多与编码技术相关的博文:编码与解码 - 腐蚀脚本

转载声明:本文允许转载,原文链接:Unicode、UTF-8 编码原理 - 腐蚀脚本


参考:

  1. https://www.cnblogs.com/liuyong18/p/13207706.html
  2. https://www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html
  3. https://juejin.cn/post/6844903494114099213#heading-5
Buy me a coffee~
室长 支付宝支付宝
室长 微信微信
0%