你每天打下的每一个字,大概率都经过同一套编码规则的翻译——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 操作系统文档
评论