Unicode
字符集:为每一个字符分配唯一的 ID(学名为码位/码点/CodePoint)
编码规则:将码位转换为字节序列的规则,编码/解码
Unicode是字符集,UTF-8、UTF-16、UTF-32等是具体的编码规则。
ASCII 码7位,共128字符,编码时用一个byte表示,第0位为奇偶校验位。
Unicode字符集为每一个字符分配一个码位,如知
的码位为30693,记作U+77E5(30693的16进制为0x77E5)。
目前的Unicode字符分为17组编排,0x0000 至 0x10FFFF,每组称为平面(Plane),而每平面拥有65536个码位,共1114112个。
-
code point: 码位
-
code unit: 指某种 Unicode 编码方式里编码一个 code point 需要的最少字节数,比如 UTF-8 需要最少一个字节,UTF-16 最少两个字节,UCS-2 两个字节,UCS-4 和 UTF-32 四个字节,后面三个是定长编码。
Unicode中的U+D800~U+DFFF码点,称之为代理码点,不表示任何字符,给UTF-16使用
编码规则
UTF-16
以 16 位为一个编码单位,最开始用2 byte表示unicode(基本平面码点),直接将码位映射位编码。
UTF-16中,大部分汉字采用两个字节编码,少量不常用汉字采用四个字节编码。
随着unicode的增补平面码点的出现,采用代理机制进行扩展。
-
Unicode字符集基本平面BMP中的字符(除U+D800~U+DFFF码点,称之为代理码点),其编码和码点值是一样的,2 byte表示;
-
Unicode字符集增补平面中的字符,通过代理码点扩展,4 byte表示。
代理Surrogate
增补平面一共有16个平面,码点编号范围为0x10000~0x10FFFF:
- 用两个代理码元表示,第一个码元的取值范围为0xD800~0xDBFF,第二个码元的取值范围为0xDC00~0xDFFF
-
总位数p + x = 20,正好为增补平面的所有码点。
-
计算时,将unicode的码位值先减去 0x10000,再用模板填充;
UTF-8**
以 8 位为一个编码单位的可变长编码,将一个码位编码为1到4个字节。常用字符更少字符数。
码位对应的模板
U+ 000 ~ U+ 007F : 0XXXXXX 共2^7位
U+ 0080 ~ U+ 07FF : 110XXXXX 10XXXXXX 共2^11 - 2^7
U+ 0800 ~ U+ FFFF : 1110XXXX 10XXXXXX 10XXXXXX 共2^16 - 2^11
U+10000 ~ U+10FFFF : 11110XXX 10XXXXXX 10XXXXXX 10XXXXXX 共2^20
知
的码位U+77E5位于第三行
7 7 E 5
0111 0111 1110 0101 二进制的77E5
--------------------------
0111 011111 100101 二进制的77E5(按照模板X对齐)
1110XXXX 10XXXXXX 10XXXXXX 模板
11100111 10011111 10100101 带入模板
E 7 9 F A 5
UTF-32
UTF-32编码以32位为编码单位。Unicode的UTF-32编码就是其对应的32位无符号整数。
字节序
字节序有两种,分别是“大端”(Big Endian, BE, 高字节存于内存低地址)和“小端”(Little Endian, LE, 高字节存于内存高地址)。
在将逻辑形式的码元序列(或可称之为逻辑编码)映射为物理形式的字节序列(或可称之为物理编码)时,因系统平台的差异,存在一个字节序(Byte-Order字节顺序)的问题。
Unicode标准建议用BOM(Byte Order Mark)来区分字节序,其值为 U+FEFF(特定的用途的unicode)。
- 字节FE(二进制为1111 1110)和FF(二进制为1111 1111)在 UTF-8 编码中永远不会出现,称之为零宽度不中断空格(ZERO WIDTH NO-BREAK SPACE);
接收到 FEFF 表示大端,接收到 FFEF 表示小端。
UTF-8 不需要BOM来表明字节顺序,但可以用BOM来表明编码方式。字符”
ZERO WIDTH NO-BREAK SPACE
“的UTF-8编码
是EF BB BF
。但,最好不要使用,防止无法识别。
Unicode编码 | 0x 00 6C 49 | 0x 02 0C 30 |
---|---|---|
UTF-16LE | FF FE 49 6C | FF FE 30 DC 43 D8 |
UTF-16BE | FE FF 49 6C | FE FF D8 43 DC 30 |
UTF-32LE | FF FE 00 00 49 6C 00 00 | FF FE 00 00 30 0C 02 00 |
UTF-32LE | 00 00 FE FF 00 00 6C 49 | 00 00 FE FF 00 02 0C 30 |
网络字节序是大端字节序。