Unicode 编码完全指南:从 ASCII 到 UTF-8 的演进
字符编码是计算机处理文本的基础。从 ASCII 到 Unicode,编码系统经历了漫长的发展过程。本文全面介绍 Unicode 编码系统。
编码发展历史
ASCII(1963 年)
美国信息交换标准代码,使用 7 位编码,共 128 个字符。
0-31: 控制字符(换行、回车等)
32-126: 可打印字符(字母、数字、标点)
127: DEL
问题: 只能表示英文字母和基本符号,无法表示中文、日文等字符。
GB2312 / GBK(中国标准)
中国制定的中文编码标准:
- GB2312:收录 6763 个汉字
- GBK:扩展到 21003 个汉字
- GB18030:收录 70000+ 汉字
问题: 不同国家有不同的编码标准,导致乱码。
Unicode(1991 年)
Unicode 的目标是统一所有字符的编码。
- 收录超过 14 万个字符
- 涵盖 150 多种文字
- 持续更新(最新版本 15.1)
Unicode 编码方式
UTF-8
变长编码,使用 1-4 个字节:
| 字节数 | 码点范围 | 编码格式 |
|---|---|---|
| 1 | U+0000 - U+007F | 0xxxxxxx |
| 2 | U+0080 - U+07FF | 110xxxxx 10xxxxxx |
| 3 | U+0800 - U+FFFF | 1110xxxx 10xxxxxx 10xxxxxx |
| 4 | U+10000 - U+10FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx |
示例:
"A" → 0x41(1字节)
"中" → 0xE4B8AD(3字节)
"😀" → 0xF09F9880(4字节)
UTF-16
变长编码,使用 2 或 4 个字节:
- 基本多语言平面(BMP):2 字节
- 补充平面:4 字节(代理对)
UTF-32
定长编码,固定使用 4 个字节。
UTF-8 的优势
- 兼容 ASCII:ASCII 字符在 UTF-8 中编码相同
- 节省空间:英文只需 1 字节
- 无字节序问题:UTF-16 有大端/小端问题
- 网络传输友好:HTTP 协议默认使用 UTF-8
编码转换
JavaScript
// 字符串 → UTF-8 字节
const encoder = new TextEncoder();
const bytes = encoder.encode("你好");
// UTF-8 字节 → 字符串
const decoder = new TextDecoder('utf-8');
const str = decoder.decode(bytes);
Java
// 字符串 → UTF-8 字节
byte[] bytes = "你好".getBytes(StandardCharsets.UTF_8);
// UTF-8 字节 → 字符串
String str = new String(bytes, StandardCharsets.UTF_8);
Python
# 字符串 → UTF-8 字节
bytes = "你好".encode('utf-8')
# UTF-8 字节 → 字符串
str = bytes.decode('utf-8')
常见编码问题
乱码的产生
原始数据(UTF-8)→ 用 GBK 解码 → 乱码
"你好" → E4BDA0E5A5BD → GBK解码 → "浣犲ソ"
解决方案
// 1. 统一使用 UTF-8
new String(bytes, StandardCharsets.UTF_8);
// 2. 设置默认编码
-Dfile.encoding=UTF-8
// 3. HTTP 请求/响应指定编码
Content-Type: application/json; charset=UTF-8
在线工具
使用 jsjson.com Unicode 工具 进行 Unicode 编码转换:
- 中文转 Unicode
- Unicode 转中文
- 实时预览
总结
Unicode 统一了全球字符的编码,UTF-8 成为互联网的标准编码。理解编码原理,可以避免开发中常见的乱码问题。