Unicode、UTF-8 编码原理
之前我们聊到了 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+0000
到U+FFFF
的字符(常用字符集),用两个字节表示。 - 编号在
U+10000
到U+10FFFF
的字符,用四个字节表示。
UTF8
同理,UTF-8 也是一种变长的编码方式。它可以使用 1~4 个字节表示一个 Unicode 字符。
UTF-8 的编码规则很简单,只有二条:
- 第一个字节的开头,有
n
个1
就代表占用n+1
个字节。 - 其余的字节,以
10
开头。 - 每个字节的其他位,依次填入字符的二进制值。(下图中的
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 编码过程:
- “马”的 Unicode 编号是:
0x9A6C
。 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 编码原理 - 腐蚀脚本
参考: