简单记录一下Unicode编码方式对比:UTF-8 vs UTF-16 vs UTF-32。
记录于此,方便自己查阅。
正文
UTF-8、UTF-16 和 UTF-32 都是 Unicode 字符集的实现方式(编码方案),它们的核心区别在于编码单元长度、空间效率和适用场景。
差异表
| 维度 | UTF-8 | UTF-16 | UTF-32 |
|---|---|---|---|
| 编码类型 | 变长编码 | 变长编码 | 定长编码 |
| 最小/最大字节 | 1 ~ 4 字节 | 2 ~ 4 字节 | 固定 4 字节 |
| ASCII 兼容 | ✅ 完美兼容(1字节) | ❌ 不兼容 | ❌ 不兼容 |
| BOM 需求 | 可选(通常不加) | 推荐(区分大小端) | 推荐(区分大小端) |
| 处理复杂度 | 高(需解析变长前缀) | 中(需处理代理对) | ⭐ 低(直接数组索引) |
| 空间效率 | ⭐⭐⭐ 优(英文极省) | ⭐⭐ 中 | ⚠️ 差(空间占用大) |
UTF-8
占用1~4 字节。
UTF-8 是目前互联网和存储的事实标准。
1 字节:
0xxxxxxx(0x00–0x7F,兼容 ASCII)2 字节:
110xxxxx 10xxxxxx3 字节:
1110xxxx 10xxxxxx 10xxxxxx(如中文“中”:E4 B8 AD)4 字节:
11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
UTF-16
占用2 或 4 字节。
UTF-16 常见于 Windows、Java、JavaScript 内部。
2 字节:基本多语言平面(BMP,U+0000–U+FFFF),如“中”(
4E 2D)。4 字节:辅助平面字符(如 Emoji 🌍),通过代理对(Surrogate Pair)表示(两个 2 字节单元拼接)。
UTF-32
UTF-32 也叫 UCS-4,每个码点固定占 4 字节。
无论字符是 ASCII(
00 00 00 41)还是中文(00 00 4E 2D),一律 4 字节。优点:字符与码点一一对应,无需解析变长规则,处理速度最快。
汉字
以汉字“中国”为例,直观对比存储空间差异
| 编码方式 | 字节数 | 十六进制表示(简化) |
|---|---|---|
| UTF-8 | 6 字节(2*3) | E4 B8 AD E5 9B BD |
| UTF-16 | 4 字节(2*2) | 4E 2D 56 FD |
| UTF-32 | 8 字节(2*4) | 00 00 4E 2D 00 00 56 FD |
观察:如果文本主要是中文,UTF-16 比 UTF-8 更省空间;但如果夹杂大量英文(如代码、JSON),UTF-8 优势巨大。
选型
在实际开发中,应根据数据特征和运行环境选择编码:
选 UTF-8
Web 开发:HTML、CSS、JavaScript、JSON、XML。
网络传输:HTTP 协议、API 接口。
文件存储:Linux/macOS 文件名、配置文件、日志。
理由:兼容 ASCII,无字节序困扰,互联网标准。
选 UTF-16
内存内部表示:Java (String)、C# (.NET)、Windows API、JavaScript 引擎内部。
跨平台 GUI:Qt、Windows 桌面应用。
理由:在纯中文或混合语言环境下,内存占用通常比 UTF-8 紧凑,且随机访问性能优于 UTF-8。
选 UTF-32
高性能计算:文本渲染引擎、正则表达式匹配、编译器词法分析。
算法研究:需要直接通过下标 O(1) 访问第 N 个字符的场景。
理由:定长特性消除了边界检查开销,但磁盘和网络传输中极少使用。
误区
Unicode ≠ UTF-8
Unicode 是字符集(定义字符与数字 ID 的映射),UTF-8/16/32 是编码方案(定义如何用字节存储这些数字)。
“UTF-8 比 UTF-16 省空间”是片面的
仅对英文成立。对于 CJK(中日韩)字符,UTF-16(2字节)通常比 UTF-8(3字节)更节省。
Emoji 在 UTF-16 中是 4 字节
很多开发者误以为 UTF-16 永远是 2 字节,实际上 Emoji(如 😂)需要一对 16 位单元(4 字节)表示。
小总
存文件、走网络,无脑 UTF-8;
写内存、做界面,常用 UTF-16;
搞算法、拼性能,考虑 UTF-32。

