先明确两个概念:
-
ASCII:美国信息交换标准代码(American Standard Code for Information Interchange),是一种字符编码标准,使用7位二进制数表示128个字符,包括英文字母、数字、标点符号和一些控制字符。ASCII 码范围从0到127。
-
Unicode:一种字符编码标准,旨在为世界上所有的字符分配唯一的代码点(code point)。代码点通常表示为
U+XXXX的形式,其中XXXX是十六进制数。 -
ASCII 和 Unicode 是字符集,这意味着它们定义了有哪些字符,并给每个字符分配一个数字。但它们没有说明这些数字是如何存储或通信的,这属于实现细节。
-
UTF-8:一种可变长度的字符编码方式,能够表示所有的 Unicode 字符。UTF-8 使用 1 到 4 个字节来编码每个字符,兼容 ASCII 编码,且在编码时尽量减少字节数。
UTF-8 编码规则
UTF-8 编码是一种变长编码方式:根据字符的 Unicode 编号,使用 1 到 4 个字节表示一个字符。建立了二进制串(或对应的十六进制)到Unicode码点的双射:
| 表示范围(10进制,个字符) | unicode码点范围 | 字节数 | 编码(二进制串) |
|---|---|---|---|
| 0 ~ 127 | U+0000 ~ U+007F | 1 | 0xxxxxxx |
| 128 ~ 2047 | U+0080 ~ U+07FF | 2 | 110xxxxx 10xxxxxx |
| 2048 ~ 65535 | U+0800 ~ U+FFFF | 3 | 1110xxxx 10xxxxxx 10xxxxxx |
| 65536 ~ 1114111 | U+10000 ~ U+10FFFF | 4 | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx |
表中的x成为数据位,可被翻译为Unicode码点信息。
前面的0,110,或10是前缀位,用于标识该字节在UTF-8编码中的位置和作用。
对于1字节编码,前缀位是0,后7位为数据位。
对于多字节编码,不同位置字节前缀位含义不同:
-
首字节 “leader byte”中
1的个数表示该字符使用的字节数,第一个0后面的位为数据位-
2字节:110xxxxx
-
3字节:1110xxxx
-
4字节:11110xxx
-
-
后续字节“trailing bytes” 以
10为前缀位,后6位为数据位
UTF-8 Unicode 转换
UTF-8 编码到 Unicode 码点
-
将UTF-8 序列转化成二进制,根据首字节的前缀确定字符的字节数
-
去掉前缀位,提取所有字节中的数据位
-
将提取的数据位从左到右拼接成完整的码点(二进制形式),转换为十六进制,查看对应的 Unicode 码点
egE4 BD A0 解码为 你
-
转换为二进制:
111001001011110110101000,根据首字节1110xxxx可知是3字节编码 -
去掉前缀位,提取数据位:
00100111101101000 -
拼接成完整的码点(二进制形式):
001001111101101000 -
转换为十六进制:
0x4F60 -
查看对应的 Unicode 码点:
U+4F60
Unicode 码点到 UTF-8 编码
-
根据 Unicode 码点的范围确定需要使用的字节数
-
根据字节数分配相应的二进制位
-
填充前缀位,形成完整的 UTF-8 编码
eg: Unicode 码点 U+4F60 编码为 E4 BD A0
-
确定字节数:
U+4F60在U+0800 ~ U+FFFF范围内,使用3字节编码 -
分配二进制位:
U+4F60的二进制表示为01001111 01100000,需要分配21个二进制位 -
填充前缀位:根据3字节编码的规则,填充前缀位,形成完整的 UTF-8 编码:
11100100 10111101 10100000