共计 2146 个字符,预计需要花费 6 分钟才能阅读完成。
你有没有遇到过这种情况:打开一个文本文件,满屏的“锟斤拷”?
或者听别人说“用 UTF‑8 保存”,但一头雾水:UTF‑8 和 Unicode 到底啥关系?
还有 GBK、GB2312,这些老古董为啥还存在?
别怕,今天咱们就用最直白的大白话,把这些“编码界的亲戚”彻底捋清楚。
一、一切从“中”字说起
计算机只认识 0 和 1。
如果我们想让计算机显示“中”这个字,就必须给它一串唯一的二进制编号。
问题是:谁来制定这个编号规则?
-
中国人说:我来!于是有了 GB2312、GBK。
-
全世界的人说:大家都别吵,统一用一个标准!于是有了 Unicode。
但故事远没有这么简单,因为 Unicode 只给编号,不包“运输”。而 UTF‑8、UTF‑16、UTF‑32 就是不同的“快递公司”。
二、土生土长的中文编码:GB2312 与 GBK
🇨🇳 GB2312(1980 年)—— 第一代“国家队”
-
既是字符集,也是编码
它规定:包含 6763 个汉字 + 600 多个符号。
同时规定:每个字符用 两个字节 表示,比如“中”→D6 D0。 -
优点:解决了早期计算机处理中文的基本问题。
-
缺点:没有繁体字,没有生僻字,人名“喆”都打不出来。
🇨🇳 GBK(1995 年)—— 扩展版“民间英雄”
-
向下兼容 GB2312,但把汉字扩充到了 21886 个(包含繁体、日韩汉字、冷僻字)。
-
仍然是双字节编码,所以“中”在 GBK 里还是
D6 D0。 -
没有正式国家标准,但 Windows 95/XP 中文版默认用它,成了事实标准。
一句话:GB2312 字太少,GBK 字更多,但都是 只服务于中文(及少量日韩)的封闭体系。它们自己就是一套完整的“字符集 + 编码实现”,不需要再依赖其他标准。
三、全球统一的“号码本”:Unicode
到了互联网时代,各国编码各自为政,跨国文本全是乱码。
于是 Unicode 联盟站出来说:我们来给地球上每一个字符(包括 emoji)分配一个全球唯一的身份证号。
-
Unicode 只做一件事:制定一个巨大的表。
“中”→ 编号U+4E2D(十六进制)
“A”→ 编号U+0041
“😊”→ 编号U+1F60A -
它不是编码! 它没有规定这个编号在计算机里要用几个字节、怎么存。
它就是一个抽象标准,相当于“世界人物编号系统”。
四、Unicode 的三个“马甲”:UTF‑8、UTF‑16、UTF‑32
Unicode 给出了编号,但计算机要存 / 要传,必须把编号变成 字节。
于是诞生了三种主流方案:
| 方案 | 中文“中”(U+4E2D) 的字节 | 特点 | 适用场景 |
|---|---|---|---|
| UTF‑8 | E4 B8 AD(3 字节) |
变长,兼容 ASCII,英文省空间 | 网页、文件、网络传输(最通用) |
| UTF‑16 | 4E 2D(2 字节) |
变长(中文大多 2 字节),Windows 内部用 | Windows、Java、.NET 内存字符串 |
| UTF‑32 | 00 00 4E 2D(4 字节) |
定长,数值 就是Unicode 编号 | 极少数需要快速随机访问的场景 |
特别注意:UTF‑32 与 Unicode 编号数值一致
-
UTF‑32 直接拿 Unicode 码点前面补 0 到 4 个字节,不做任何变换。
所以U+4E2D的 UTF‑32 就是00 00 4E 2D。 -
而 UTF‑8 和 UTF‑16 都会改变原始数值(UTF‑16 对辅助平面用代理对,数值就不等于码点了)。
五、一张关系图彻底搞懂

关键区别总结
-
GB2312 / GBK:像是一个自给自足的小王国,既有自己的“国民名单”(字符集),又有自己的“身份证格式”(编码)。
-
Unicode:像是一个“全球公民编号委员会”,只给编号,不发身份证。
-
UTF‑8/16/32:像是不同的“身份证制作规范”,把编号变成实物字节。
六、常见误区(选择题)
1.“UTF‑8 是一种 Unicode”
❌ 错。UTF‑8 是 Unicode 的一种实现,不是 Unicode 本身。
2.“GBK 像 Unicode 一样只是标准,不是实现”
❌ 错。GBK 自己既定义了字符集也定义了编码实现。
3.“UTF‑32 和 Unicode 编号不一样”
❌ 错。数值上完全一样,只是加上了字节序(大端 / 小端)。
4.“UTF‑8 不能表示所有 Unicode 字符”
❌ 错。UTF‑8 可以表示全部 100 多万个 Unicode 码点。
七、日常开发怎么选?
| 场景 | 推荐编码 | 原因 |
|---|---|---|
| 新项目、网页、数据库 | UTF‑8 | 全球通用,不乱码,支持 emoji |
| 写代码(源代码文件) | UTF‑8 | 跨平台,Git 友好,主流 IDE 默认 |
| 处理来自 Windows 中文老软件的数据 | GBK 或 GB18030 | 必须先正确解码,再转 UTF‑8 |
| 存储超大中文文本(几 GB) | UTF‑8 仍推荐 | 除非存储极度受限,否则通用性更重要 |
一句话结论:除非历史债务,否则无脑用 UTF‑8。
八、彩蛋:“锟斤拷”是怎么来的?
当你用 GBK 去打开一个 UTF‑8 文件时,系统遇到无法解码的字节就会替换成 �(U+FFFD)。
而这个 � 在 GBK 下恰好被解释为“锟”和“斤”的两个字节……于是满屏“锟斤拷”。
解法:统一用 UTF‑8 存,统一用 UTF‑8 读。
写在最后
-
GB2312 / GBK:中文编码的老前辈,功德无量,但该退休了。
-
Unicode:全球字符的身份证系统,只给编号,不包实现。
-
UTF‑8:目前最通用的实现方式,互联网的默认语言。
希望现在你再看到“编码”二字,心里能浮现出那张关系图。
如果下次同事再问你“UTF‑8 和 Unicode 有啥区别”,直接把这篇博客甩给他 😉