一、UTF-8
UTF-8 的全称为: Unicode Transformation Format - 8 - bit
- Unicode 统一字符集,给世界上所有文字分配唯一编号
- Transformation Format 转换格式
- 8-bit 以8位(一个字节) 为基本单位进行编码
UTF-8 是一种把Unicode字符编码成1~4个字节的编码方式
变长编码:
- 英文: 1个字节
- 拉丁字母: 2个字节 (拉丁字母和希腊字母)
- 中文: 3个字节 (大多数常见汉字)
- Emoji: 4字节 (包括生僻字符)
编码规则:
- 对于长度为1字节的字符,将最高位设置为0.
- 对于长度为n字节的字符(n > 1),将首个字节的高n位都设置为1,第n+1位设置为0;从第二个字节开始,将每个字节的高2位都设置为10;
理解: 如果读到一个Byte,那么就取第一位,如果是0,那么就是Ascii码。如果是1,那么继续取值,直到0,有几个1就是几个字符长度。读取后面字符后,组装成一个有效的Unicode码。
举例: "算"字的
Unicode是 U+7B97:
7 B 9 7
0111 1011 1001 0111
UTF-8的编码为 0xE7AE97
E 7 A E 9 7
1110 0111 1010 1110 1001 0111
UTF-16的编码为 0x7B97
7 B 9 7
0111 1011 1001 0111
二、 UTF-16编码: 2或4字节
- 2个字节: 当码点在 U+0000 到 U+FFFF,不在代理区 U+D800 到 U+FFFF
- 4个字节: 当码点在U+10000 到 U+10FFFF时,使用代理对计算
代理对计算规则:
Unicode有一段特别的区间: U+D800 到 U+DFFFF 不是字符,仅仅是UTF-16的代理对。
当码点 >= 0x10000 时:
-
减去0x10000
-
- U = codePoint - 0x10000
-
拆成高10位和低10位
-
- high = U >> 10
- low = U & 0x3FF
-
加上代理基值
-
- 高代理 = 0xD800 + high
- 低代理 = 0xDC00 + low
-
得到4字节的UTF-16编码
解析UTF-16逻辑:
- 先取2个字节;
- 如果该值落在0xD800到0xDBFF,说明这是高代理,需要再取2个字节组成4个字节字符。
- 再取的2个字节在0xDC00到0xDFFF内。
- 否则该字符就是2字节表示。
举例:
- 读取到 0xD83D
- 因为0xD83D在 0xD800到0xDBFF之间,说明是高代理 0xD83D - 0xD800 = 0x3D
- 再获取2字节,读取到0xDE00
- 因为0xDE00在0xDC00到0xDFFFF之间,说明是低代理 0xDE00 - 0xDC00 = 0x200
- 计算 0x3D << 10 + 0x200 + 0x10000 = 0xF400 + 0x10200 = 0x1F600
结果为 0xD83D的Unicode值为 😀(U+1F600)
知识点:
- 使用UTF-16编码的语言有Java、JavaScript、TypeScript和C#。
- 网络传输时使用UTF-8格式,以达到最优的兼容性和空间效率。