# 乱码从哪来：GBK、Big5 和 UTF-8

> 适合谁看：打开文件、网页、表格时遇到乱码，想知道原因和解决办法的人。

## 字符集和编码方式

- **字符集**：收哪些字、每个字什么编号（如 Unicode、GB 18030）；
- **编码方式**：把编号变成字节存起来的规则（如 UTF-8、UTF-16、GBK）。

同一个「中」字，用 UTF-8 存是 3 个字节，用 GBK 存是 2 个字节。读的时候用错规则，就会得到乱码。

## 常见的中文编码

| 编码 | 范围 | 说明 |
|---|---|---|
| GB 2312 | 6763 个汉字 | 早期简体中文编码 |
| GBK | 两万多个汉字 | GB 2312 的扩展，Windows 简体中文系统长期默认使用 |
| GB 18030 | 全部 Unicode 字符 | 国家标准，兼容 GBK，见[《GB 18030：中文编码的国家标准》](https://docs.cocobook.com/link/1280) |
| Big5 | 繁体常用字 | 台湾、香港早期常用 |
| UTF-8 | 全部 Unicode 字符 | 网页和现代软件的事实标准 |

## 典型乱码现象

- **「锟斤拷」**：一段文字曾经被替换成了替代字符「�」，再用 GBK 显示出来；原文已经丢失，无法还原；
- **「浣犲ソ」这类怪字**：UTF-8 的文字被当成 GBK 读了，用正确的编码重新打开就能恢复；
- **CSV 用 Excel 打开乱码**：文件是 UTF-8 编码，Excel 按系统默认编码打开。可以在 Excel 中用「数据 → 从文本/CSV」导入并选择 UTF-8，或保存为带 BOM 的 UTF-8。

## 怎么避免

1. **统一用 UTF-8**：网页、数据库、接口、文件都用 UTF-8；
2. **网页声明编码**：`<meta charset="utf-8">` 写在 `<head>` 最前面；
3. **数据库用完整的 UTF-8**：例如 MySQL 要用 `utf8mb4`，见[《人名、地名里的生僻字：系统怎么做》](https://docs.cocobook.com/link/1286)；
4. **和老系统交换数据时**：明确约定编码，需要中文国标编码时用 GB 18030 而不是 GBK，GBK 存不下扩展区的生僻字。

## 乱码和方框不是一回事

乱码是**编码**问题，换字体没用；方框是**字体缺字**，换字体就好。区别见[《生僻字为什么打不出、显示不了》](https://docs.cocobook.com/link/1278)。

<p class="cb-refs-src" style="display:none;"><a href="https://docs.cocobook.com/link/1307#bkmrk-src-e04-mojibake">参考资料</a><span class="cb-refs-n">4</span><span class="cb-refs-t">Character encodings for beginners</span><span class="cb-refs-t">Declaring character encodings in HTML</span><span class="cb-refs-t">Encoding Standard</span></p>