技术

UTF-8:一套运行了三十年的编码设计

字号
UTF-8:一套运行了三十年的编码设计

你每天打下的每一个字,大概率都经过同一套编码规则的翻译——UTF-8。它的设计精巧而克制,值得拆开看一眼。

一、编码规则

UTF-8 是变长编码,按码点大小使用 1 到 4 个字节,字节的第一位就是它的「身份标识」:

码点范围 字节数 位型
U+0000 – U+007F 1 0xxxxxxx
U+0080 – U+07FF 2 110xxxxx 10xxxxxx
U+0800 – U+FFFF 3 1110xxxx 10xxxxxx 10xxxxxx
U+10000 – U+10FFFF 4 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

规则可归纳为三句话:首字节以几个连续的 1 开头,就表示这个字符共占几个字节;后续字节一律以 10 开头;x 的位置填入码点的二进制位,从右往左对齐,不足补零。

以「中」(U+4E2D)为例:落在三字节区间,二进制 0100 1110 0010 1101 填入 1110xxxx 10xxxxxx 10xxxxxx 的空位,得到 E4 B8 AD。

二、三个设计上的巧思

1. 与 ASCII 完全兼容。 单字节区 0xxxxxxx 与 ASCII 逐字节相同。任何纯 ASCII 文本天然就是合法的 UTF-8,旧系统无需修改即可过渡。

2. 自同步。 续字节固定以 10 开头。解码器在任何位置丢失同步(比如从字节流中间开始读),最多跳过一个字节就能重新找到字符边界——找到 10 就跳过,找到非 10 的首字节就是新字符的开始。这个特性让「按字节切分数据流」变得安全,是 UTF-8 能统治网络传输的重要原因。

3. 字节序无关。 UTF-16 需要靠 BOM(字节顺序标记)声明大小端,跨系统交换文件时踩坑无数;UTF-8 的每个字符内部没有字节序问题,天然适合存储与网络。

三、边界与限制

  • 可编码范围为 U+0000 到 U+10FFFF,这也是 Unicode 本身的上限;超出非法。
  • Unicode 的代理区(U+D800–U+DFFF)不允许以 UTF-8 编码,杜绝了与 UTF-16 的歧义。
  • 最长四字节是刻意设计:10FFFF 已经用满了 21 位,四字节的位型恰好提供 21 个 x。

参考与核查

  • RFC 3629(2003,Internet 标准 STD 63):编码规则、代理区禁令、安全性考虑均出自此文档:https://www.rfc-editor.org/rfc/rfc3629
  • 标准化沿革清晰可查:RFC 2044(1996)→ RFC 2279(1998)→ RFC 3629(2003,收窄至四字节并禁用代理区)
  • 设计者 Ken Thompson 与 Rob Pike 于 1992 年提出、1993 年在 USENIX 会议公开发表,最早的完整实现见 Plan 9 操作系统文档

评论