字符编码入门:Unicode 是值,UTF 是编码,GBK 是另一套

2 阅读3分钟

字符编码入门:Unicode 是值,UTF 是编码,GBK 是另一套

一、两个不同层次的东西

处理文本时有两件独立的事,很多人会混:

第一层:字符编码方案 —— 决定"字符 ↔ 字节"怎么对应。

第二层:转义/包装手段 —— 当字节必须穿过只认 ASCII 的通道时,临时把字节包装成 ASCII 字符串。


二、第一层:字符编码方案

1. Unicode 与 UTF-8/16/32

Unicode 是编号表:每个字符一个编号(码点)。"中"= U+4E2D,"A"= U+0041。

UTF-8/16/32 是把编号写成字节的规则:

字符Unicode 编号UTF-8 字节UTF-16 字节UTF-32 字节
中U+4E2DE4 B8 AD(3 字节)4E 2D(2 字节)00 00 4E 2D(4 字节)
AU+004141(1 字节)00 4100 00 00 41
  • UTF-8:1–4 字节变长,兼容 ASCII,无字节序问题 → 互联网主流。
  • UTF-16:1–2 个 16 位单元,有代理对、有大小端 → 内存/旧系统常见。
  • UTF-32:固定 4 字节,简单但浪费。

优点:Unicode 一套编号覆盖全世界;UTF-8 兼容 ASCII。

缺点:UTF-16 麻烦;UTF-32 占空间。

2. ASCII

128 个字符(0–127),英文、数字、标点、控制符。字符集和编码合一,一字符一字节。 "A"=65。"中"没有。

和 Unicode 的关系:ASCII 是 Unicode 的子集,U+0000–U+007F 完全一致。纯 ASCII 文本天然是合法 UTF-8。

3. 区域性旧编码(和 UTF-8 同一层,是竞争对手)

这些既是字符表也是编码规则,绑在一起,一步到位给出字节:

编码用途例子
GB2312简体中文,6763 常用汉字"中" → D6 D0
GBKGB2312 扩展,2 万多汉字同上
GB18030覆盖全部 Unicode,1/2/4 字节变长—
Big5繁体中文—
Shift_JIS日文"あ" → 82 A0
ISO-8859-1西欧"é" → E9

优点:当年各自解决本地语言,省空间(中文 2 字节)。

缺点:互不兼容,同一串字节在不同编码下意思不同 → 乱码。

和 Unicode 的关键区别:

  • Unicode 分两步:字符 → 编号 → 字节。
  • GBK 等一步到位:字符 → 字节,没有中间编号层。
  • 所以 GBK 不是"Unicode 的某种编码",它是独立规范,和 UTF-8 平级。

三、第二层:转义/包装手段

它们不是字符编码方案,是"把字节或码点包装成 ASCII 字符串"的临时手段,收到后要解码还原。

为什么需要:有些通道只认 ASCII(URL、邮件头、源码文件),非 ASCII 字节过不去。

例子(都以"中"为例,底层用 UTF-8):

手段写法说明
Unicode 转义\u4E2D直接写码点,源码里用
HTML 实体中 或 中网页里用,浏览器解码
URL 编码%E4%B8%AD把 UTF-8 字节 E4 B8 AD 每个字节写成 %XX
Base645Lit把字节 E4 B8 AD 重新映射到 64 个安全字符

优点:让非 ASCII 内容安全穿过 ASCII 通道。

缺点:变长、不可读、需要解码。

关键:包装手段和底层编码独立。GBK 也能被 URL 编码:%D6%D0。

类比:UTF-8/GBK 是"语言本身",URL 编码/Base64 是"运输包装"。


四、串成一条线

字符"中"
  ├─ GBK(一步到位):→ 字节 D6 D0
  └─ Unicode(两步):
        查编号 → U+4E2D
          ├─ UTF-8 → 字节 E4 B8 AD
          │     ├─ URL 编码 → %E4%B8%AD
          │     └─ Base64 → 5Lit
          ├─ UTF-16 → 字节 4E 2D
          └─ 转义序列 \u4E2D(直接写编号)