Unicode编码的二进制编码方案
unicode介绍
unicode 编码为世界上所有字符都分配了一个唯一的数字编号。编号范围从 0x000000
到 0x10FFFF
。编号与每个字符都一一对应。
但是 unicode 本身只规定了每个字符的编号是多少,并没有规定编号如何存储。
所以就有了多种 unicode 的二进制存储方案。
unicode 二进制存储方案
二进制的存储方案主要由以下几种:
- UTF-32
- UTF-16
- UTF-8
UTF-32
这种方案比较简单,UTF-32 用四个字节来表示一个字符(不论编号大小统一用四个字节来存储二进制值),即每次处理都会取四个字节为一个处理单元。
例如:“赑” 的 unicode 编号为 36177,十六进制值为:0x8d51
utf-32 二进制编码为:
00000000 00000000 10001101 01010001
因为在内存中存储数据有大小端两种模式,所以UTF-32中也有两种编码方式:
- UTF-32BE:大端序
- UTF-32-LE:小端序
UTF32编码的缺点:
- 浪费存储空间:不论编号大小,统一使用4个字节表示。
UTF-16
UTF-16 使用变长字节表示
- 对于编号在 0x 00 00 到 0x FF FF 之间的字符(常用字符集),直接使用两个字节表示。
- 对于编号在 0x 1 00 00 到 0x 10 FF FF 之间的字符,需要用四个字节来表示
UTF-16 也有字节序的问题所以也有:
-
UTF-16BE :大端序
-
UTF-16LE:小端序
UTF-16 相比较 UTF-32 能够更有效的节省存储空间。
UTF-8
UTF-8 也是使用变长字节表示, 使用的字节数与 unicode 的编号大小有关,编号越小使用的字节越少,编号大的则使用的字节就越多,使用的字节个数范围从 1 个字节到 4 个字节。
unicode编号和 utf-8 使用字节数对比表:
编号范围 | UTF-8 字节数 |
---|---|
0x00 ~ 0x7F ( 0 ~ 127 ) | 1 |
0x80 ~ 0x7FF ( 128 ~ 2047 ) | 2 |
0x800 ~ 0xFFFF ( 2048 ~ 65535 ) | 3 |
0x10000 ~ 0x10FFFF ( > 65535) | 4 |
UTF-8 编码规则:
-
使用单字节表示的字符,字节的第一位设置为 0,后面的 7 位为这个符号的unicode编号。
例如:
‘W’ 这个字符的unicode 编号为127,则使用单个字节来表示。字节的第1 位为 0,剩下的7为来表示 127 本身。则 ‘W’ 的UTF-8二进制编码为:
0 1111111
-
使用n(n > 1)字节表示的字符,第一个字节的前 n 位都设置为 1,第 n+1位设置为 0,其余所有字节的前两位都设为10,剩下的所有的没有被设置的二进制位用来表示 该字符的 unicode 编号。
例如:
汉字:’赑‘ unicode编号为 36177 。则 UTF-8 用3 个字节来表示这个汉字。
根据规则,有如下utf-8编码过程:
-
第一个字节的前 3 位都设置为 1,第 4 位设置为 0:
1110xxxx xxxxxxxx xxxxxxxx
-
第 2,3 字节的前两位设置为 10:
1110xxxx 10xxxxxx 10xxxxxx
-
剩下的所有二进制位 x 用来表示 unicode 编号值 36177(十进制),二进制(10001101 01010001)
11101000 10110101 10010001
-
可以发现剩下的 x 都已经被用来表示 unicode 编号了。
-
UTF-8 的处理单元为1个字节,所以不需要考虑字节序
很显然,UTF-8 能够合理有效的利用空间来存储 unicode 字符。所以很多地方都普遍使用 UTF-8 编码。