各国各自给汉字/假名续表的时代(BIG5 繁体、GBK 简体、Shift_JIS 日文)留下一地【乱码】,Unicode 用【给全世界每个字发唯一编号】终结割据,再配上变长编码 UTF-8——2026 年它已占网页的 99.1%。
3-9 说 ASCII 只有 128 位、装不下汉字,这一篇讲各国续表续出的乱世与 Unicode 的统一。教材是日文书,本节标题带【日文】视角——笔记按中文语境重排,五族编码一并讲清。回收树莓派课 3-6 的换行符坑(同一类【标准不统一】问题)。
一、编码割据时代:一个字节装不下汉字
ASCII 是 7 位、128 个字符——英文够用,汉字八万多个,128 个位置连零头都装不下。各语言圈的解法一样:拿出编号 128 以上的位置继续编码,于是:
| 编码 | 服务对象 | 备注 |
|---|---|---|
| GB2312/GBK/GB18030 | 简体中文 | GBK 兼容 GB2312;GB18030 是现行强制国标 |
| BIG5(大五码) | 繁体中文 | 台湾地区通行 |
| Shift_JIS/EUC-JP | 日文 | 假名+JIS 汉字 |
| EUC-KR | 韩文 |
致命问题:同一串字节,按 GBK 读是一句话、按 Shift_JIS 读是另一句话、按 BIG5 读是第三句——编码和字表一旦错配,就是乱码。它不是【字坏了】,是【按错的对照表读的】。
二、Unicode + UTF-8:编号统一、存储变长
Unicode(1991 年起)干的第一件事:统一编号空间——每个字符只有一个全球唯一编号(码点)。2026 年的最新版是 Unicode 17.0(2025-09 发布,新增 4803 个字符,总数 159,801 个)。
但【编号】不等于【怎么存进字节】——第二件事由 UTF-8 完成:
- ASCII 字符(英文、数字、半角符号):1 字节,与老 ASCII 完全兼容;
- 常用汉字:3 字节;
- 生僻字/Emoji:4 字节。
变长的妙处:英文为主的文本不浪费,中文也可接受——加上【向下兼容 ASCII】这一条,UTF-8 从 2008 年起登顶网页,2026 年 99.1% 的网站用它(W3Techs 2026-09 统计)。
三、中国现状:GB 18030-2022 是强制国标
Unicode 解决了【全球互通】,中国另有自己的现行标准:GB 18030-2022《信息技术 中文编码字符集》(2022-07-19 发布、2023-08-01 起强制实施)——收录 87887 个汉字及部首(含《通用规范汉字表》全部、人名地名生僻字)+ 10 种少数民族文字,向下兼容 GBK。政务、金融等系统按国标要求支持它。日常开发记一条就够:新项目一律 UTF-8;对接国内老系统时留意 GB18030/GBK。
四、动手 Demo:同一个字的三种字节身材
s = "你"
print(s.encode("utf-8")) # b'\xe4\xbd\xa0' 3 字节
print(s.encode("gbk")) # b'\xc4\xe3' 2 字节
print(s.encode("shift_jis")) # UnicodeEncodeError!
看到什么算成功:前两行打印出字节数组,第三行报错——shift_jis codec can't encode character。
读结果:同一个【你】,UTF-8 给 3 字节、GBK 给 2 字节——字节串相同与否,取决于用什么编码看;而 Shift_JIS 的字表里根本没有【你】(它是日文汉字集,装的主要是日本常用的汉字),编码直接失败。这一幕把三件事全演示了:变长、字表不同、以及【编码不过去】比乱码更诚实。
五、30 秒实验:防乱码一条纪律
Python 里读文件永远写 open("f.txt", encoding="utf-8")——不写 encoding 时 Python 按系统默认走(Windows 中文环境是 GBK),拿到一份 UTF-8 文件就乱码。30 秒:故意用 GBK 读一段 UTF-8 的【你好】,看它变成什么——从此 encoding 参数终生带。
六、常见误区
- 【乱码是文件被写坏了】——错。字节完好无损,只是【编码的对照表】用错了;用对编码重读就恢复。真正怕的是【按错误编码存回】——那次才真的丢字。
- 【Unicode 就是 UTF-8】——错。Unicode 是【编号表】(抽象层),UTF-8/UTF-16/UTF-32 是【把编号写成字节】的不同方案(存储层)。
- 【GBK 已废弃不用管】——分两面:新项目确实一律 UTF-8;但国内存量老系统、部分 Windows 环境默认仍是 GBK 家族,对接旧系统是 GBK 的主战场——处理外贸老网站、老数据库导出文件时都会遇到。
自测三问(点开对答案)
1. **乱码的根本原因是什么?** 答:写入时用的编码与读取时用的编码(字表)错配——同一串字节被按错误的对照表翻译;字节本身没坏。 2. **UTF-8 为什么能赢?** 答:向下兼容 ASCII(英文零成本迁移)+变长(英文 1 字节、中文 3 字节不浪费)——2026 年占网页 99.1%。 3. **GB 18030-2022 是什么地位?** 答:中国现行强制国标(2023-08-01 实施),收录 8.8 万汉字兼容 GBK——国内政企系统的新建与验收按它执行。- ☐ 下一节(3-11 结构体、枚举类型)
相关笔记
- 字符编码、字符串、NULL字符 —— ASCII 与字符串的底子
- 树莓派 6-6 · Python 列表与字符串 —— 字符按字符字节按字节的坑
- 网络 4.2 · 制作Web网页 —— 网页 charset 标签的另一视角
- ⌨️ 编程原理 · 索引 —— 全课路线图