806 字
4 分钟
UTF-8 编码与 Unicode,ASCII

先明确两个概念:

  • 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 ~ 127U+0000 ~ U+007F10xxxxxxx
128 ~ 2047U+0080 ~ U+07FF2110xxxxx 10xxxxxx
2048 ~ 65535U+0800 ~ U+FFFF31110xxxx 10xxxxxx 10xxxxxx
65536 ~ 1114111U+10000 ~ U+10FFFF411110xxx 10xxxxxx 10xxxxxx 10xxxxxx

表中的x成为数据位,可被翻译为Unicode码点信息。

前面的0110,或10前缀位,用于标识该字节在UTF-8编码中的位置和作用。

对于1字节编码,前缀位是0,后7位为数据位。

对于多字节编码,不同位置字节前缀位含义不同:

  • 首字节 “leader byte”中1的个数表示该字符使用的字节数,第一个0后面的位为数据位

    • 2字节:110xxxxx

    • 3字节:1110xxxx

    • 4字节:11110xxx

  • 后续字节“trailing bytes” 以10为前缀位,后6位为数据位

UTF-8 \Leftrightarrow Unicode 转换#

UTF-8 编码到 Unicode 码点#

  1. 将UTF-8 序列转化成二进制,根据首字节的前缀确定字符的字节数

  2. 去掉前缀位,提取所有字节中的数据位

  3. 将提取的数据位从左到右拼接成完整的码点(二进制形式),转换为十六进制,查看对应的 Unicode 码点

eg 字节 E4 BD A0 解码为

  1. 转换为二进制:11100100 10111101 10101000,根据首字节 1110xxxx 可知是3字节编码

  2. 去掉前缀位,提取数据位:00100 111101 101000

  3. 拼接成完整的码点(二进制形式):001001111101101000

  4. 转换为十六进制:0x4F60

  5. 查看对应的 Unicode 码点:U+4F60

Unicode 码点到 UTF-8 编码#

  1. 根据 Unicode 码点的范围确定需要使用的字节数

  2. 根据字节数分配相应的二进制位

  3. 填充前缀位,形成完整的 UTF-8 编码

eg: Unicode 码点 U+4F60 编码为 E4 BD A0

  1. 确定字节数:U+4F60U+0800 ~ U+FFFF 范围内,使用3字节编码

  2. 分配二进制位:U+4F60 的二进制表示为 01001111 01100000,需要分配21个二进制位

  3. 填充前缀位:根据3字节编码的规则,填充前缀位,形成完整的 UTF-8 编码:11100100 10111101 10100000

UTF-8 编码与 Unicode,ASCII
https://biscuit0613.github.io/posts/csapp/csapp_unicode/
作者
Biscuit
发布于
2025-11-01
许可协议
CC BY-NC-SA 4.0