Unicode 是字符的“全球唯一身份证号”(码点),而 UTF-8、UTF-16、UTF-32 是将这个身份证号“书写”或“传输”成不同格式的规则。

utf-32码元长度 固定 4 字节,32位
utf-16变长 (2 或 4 字节),16位或32位
utf-8变长 (1 至 4 字节),8位到32位。
优缺点对比:
1. UTF-32:简单粗暴的“身份证复印件”
· 原理:每个字符的“身份证号”都用 完整的4个字节 记录下来。例如:A编码U+0041 -> 00000041。
· 优点:极速。由于固定长度,要找到字符串中第 N 个字符,直接用 N*4 计算地址即可。
· 缺点:极其浪费空间。存储一个英文文档,文件大小会是 ASCII 编码的 4 倍。一个简单的表情符号 (U+1F600) 也需要 4 字节,和字母 A 一样。
· 比喻:不管你是谁,都给你分配一个四室一厅的大房子(4字节)。存储一篇文章就像建了一个全是四室一厅的小区,许多房间是空的。

2. UTF-16:“两居室为主,必要时打通”
· 原理:大部分二个字节,偏僻字4个字节
· 对于 BMP 内字符 (U+0000 to U+FFFF): 直接用一个 2 字节的“码元”表明。
例如:
· A 编码(U+0041) -> 0041
· 中编码 (U+4E2D) -> 4E2D
· 对于辅助平面字符 (U+10000 and above): 使用 代理对。这是一个精妙的算法,将一个码点拆分成两个 2 字节的码元(一个高代理,一个低代理)。
· (U+1F600) -> 代理对 D83D DE00 (共4字节)。
· 优点:对于 BMP 内文字(如几乎所有中文、日文、韩文字符)超级紧凑,处理速度也较快。

· 缺点:
1. 不是真正的定长,存在“代理对”,处理时需要额外判断。
2. 有字节序问题,需要 BOM (FF FE 或 FE FF) 来声明文件是“大头”还是“小头”存储。
3. 对于纯 ASCII 文本,效率是 UTF-8 的一半(每个字符2字节 vs 1字节)。
· 比喻:默认给每人一间两居室(2字节)。如果人口太多(生僻字、表情),就把两间相邻的两居室打通,变成一套大房子(4字节)。
3. UTF-8:智能高效的“弹性公寓”
· 原理:基于字符码点的范围,智能地分配 1 到 4 个字节。
· ASCII (U+0000 to U+007F): 1 字节,且与 ASCII 完全一致。这是其决定性优势。
例如:
· A (U+0041) -> 41
· 拉丁文、希腊文等 (U+0080 to U+07FF): 2 字节。
· 绝大部分汉字 (U+0800 to U+FFFF): 3 字节。
· 中 (U+4E2D) -> E4 B8 AD (3字节)
· 辅助平面字符 (U+10000 and above): 4 字节。
· (U+1F600) -> F0 9F 98 80 (4字节)
· 优点:
1. 极致空间效率:对全球互联网上占比最大的 ASCII 字符(代码、标记、英文)100% 高效。
2. 无字节序问题:字节流本身定义了完整性,无需 BOM。
3. 高度兼容:任何能处理 ASCII 的旧系统都能无损读取 UTF-8 文件中的 ASCII 部分。
4. 自同步:可以从字节流中间开始解析,快速找到下一个合法字符的起始位置。
· 缺点:处理速度最慢。由于是变长的,无法直接跳到第 N 个字符,必须从头数起。
· 比喻:根据家庭成员多少,分配不同大小的公寓(1-4字节)。一个人住单间(1字节),三口之家住三居室(3字节)。这样整个社区的土地利用率最高。

为什么 UTF-8 成为互联网的绝对王者?
1. 历史惯性(兼容性):互联网的基础协议(如HTTP、HTML)和大量遗产系统都基于 ASCII。UTF-8 无缝兼容了这段历史。
2. 空间即是金钱:更小的文件尺寸意味着更快的网络传输、更少的带宽成本和存储成本。UTF-8 在绝大多数场景下尺寸最优。
3. 简化与统一:UTF-8 消除了“字节序”的烦恼,BOM 在 UTF-8 中不仅不必要,一般还被提议省略。

应用中的选择
· 存储与传输(文件、网络协议、数据库、JSON/XML): 无脑选择 UTF-8。这是现代软件开发的黄金标准。
· 特定系统或语言内部:
· 在 Windows 内核、.NET、Java (早期版本)、JavaScript (ECMAScript 规范) 中,字符串在内存中一般以 UTF-16 形式存在,由于其设计年代 UTF-8 优势未显,且 BMP 字符处理方便。
· Linux、现代编程语言(Go, Rust, Python 3 默认字符串) 则更倾向于使用 UTF-8 作为内部表明或直接处理。
· UTF-32 极少直接使用,但一些文本处理库或语言(如某些版本的 Python)在内部可能会用其来简化复杂的字形操作。
理解它们的差异,能让你在遇到乱码、进行国际化开发或性能优化时,做出正确的决策。记住通用法则:对外(存储/交换)用 UTF-8,对内(内存处理)遵循你所用的平台或语言规范。