文本编码详解:UTF-8、ASCII、Unicode 与字符集

· 12分钟阅读

目录

每次你输入消息、保存文档或浏览网站时,字符编码都在幕后工作,将人类可读的文本转换为计算机能理解的二进制数据。尽管编码是所有数字通信的基础,但它仍然是计算机领域最容易被误解的方面之一。

本综合指南解释了关于文本编码你需要知道的一切,从 ASCII 的基础知识到 Unicode 和 UTF-8 的复杂性。无论你是正在调试编码问题的开发者,还是只是对计算机如何处理文本感到好奇,你都能在这里找到实用的见解和解决方案。

什么是字符编码?

字符编码是将字符——字母、数字、符号和特殊字符——映射到计算机可以存储和处理的数值的系统。当你在键盘上输入字母"A"时,你的计算机并不存储字母本身。相反,它存储一个数字(在 ASCII 中是 65),并使用编码方案在显示时将该数字转换回"A"。

可以把字符编码想象成人类语言和计算机语言之间的翻译词典。没有这本词典,文本将是无意义的字节序列,无法正确解释。

编码过程在两个方向上工作:

当编码和解码使用不同的方案时就会出现问题。想象一下,如果你用一种密码加密消息,然后试图用另一种密码解密——你会得到乱码。文本编码不匹配时也会发生同样的事情,导致字符损坏或臭名昭著的"乱码"(稍后详述)。

专业提示:使用我们的文本编码器工具,准确查看不同编码方案如何表示相同的文本。这种实践方法有助于揭开编码过程的神秘面纱。

ASCII:文本编码的基础

ASCII(美国信息交换标准代码)开发于 1963 年,成为现代文本编码的基础。它使用 7 位来表示 128 个字符,这对于当时的英文文本和基本计算需求来说已经足够。

ASCII 字符集分为几个范围,每个范围都有特定的用途:

范围 字符 数量 用途
0-31 控制字符 32 不可打印的命令(制表符、换行符、回车符)
32-47 标点符号与符号 16 空格、!、"、#、$、%、&、'、(、)、*、+、逗号、-、.、/
48-57 数字 10 0-9
58-64 标点符号 7 :、;、<、=、>、?、@
65-90 大写字母 26 A-Z
91-96 标点符号 6 [、\、]、^、_、`
97-122 小写字母 26 a-z
123-126 标点符号 4 {、|、}、~
127 删除 1 DEL 控制字符

ASCII 的局限性

ASCII 对英文文本来说非常完美,但对于国际通信有严重的局限性:

这些局限性导致了"扩展 ASCII"变体的创建,如 ISO-8859-1(Latin-1),它使用第 8 位来添加 128 个字符。然而,不同地区创建了不兼容的扩展,导致相同的字节值根据使用的代码页表示不同的字符。

ASCII 的持久影响

尽管有局限性,ASCII 在今天仍然相关。UTF-8(主流的现代编码)的前 128 个字符与 ASCII 完全相同,确保了向后兼容性。这意味着任何有效的 ASCII 文本也是有效的 UTF-8,使迁移无缝进行。

ASCII 的简单性也使其成为只需要基本英文文本的协议、文件格式和系统的理想选择。编程语言、命令行界面和网络协议仍然严重依赖 ASCII 字符。

Unicode:通用字符集

Unicode 创建于 1991 年,旨在解决 ASCII 及其扩展无法解决的根本问题:在单一统一标准中表示世界上所有的书写系统。Unicode 不是有几十种不兼容的编码方案,而是提供了一个适用于所有人的系统。

Unicode 本身不是一种编码——它是一个字符集,为每个字符分配一个称为码位的唯一数字。截至 Unicode 15.1(2023 年发布),该标准包含超过 149,000 个字符,涵盖 161 种文字和符号集。

理解码位

码位以 U+XXXX 格式书写,其中 XXXX 是十六进制数字。以下是一些示例:

Unicode 代码空间范围从 U+0000 到 U+10FFFF,提供了 1,114,112 个可能的码位空间。这些被组织成 17 个平面,每个平面有 65,536 个码位。

Unicode 平面

最重要的平面包括:

快速提示:BMP(平面 0)中的字符可以用 16 位表示,而其他平面中的字符需要更多位。在 UTF-8、UTF-16 和 UTF-32 之间选择时,这种区别很重要。

Unicode 规范化

Unicode 的一个复杂之处在于某些字符可以用多种方式表示。例如,字符"é"可以编码为:

两种表示看起来相同,但具有不同的字节序列。Unicode 规范化形式(NFD、NFC、NFKD、NFKC)提供了在这些表示之间转换的标准方法,确保一致的比较和搜索。

UTF-8:互联网的标准编码

UTF-8(Unicode 转换格式 - 8 位)是互联网上使用最广泛的字符编码,占所有网页的 98% 以上。它由 Ken Thompson 和 Rob Pike 于 1992 年设计,已成为文本编码的事实标准。

UTF-8 是一种可变长度编码,每个字符使用 1 到 4 个字节。这种巧妙的设计提供了几个优势:

UTF-8 的工作原理

UTF-8 使用以下方案编码字符:

码位范围 字节数 字节模式 示例字符
U+0000 到 U+007F 1 0xxxxxxx ASCII 字符(A、5、$)
U+0080 到 U+07FF 2 110xxxxx 10xxxxxx 拉丁扩展、希腊文、西里尔文(é、α、Ж)
U+0800 到 U+FFFF 3 1110xxxx 10xxxxxx 10xxxxxx 大多数亚洲文字、符号(中、ह、€)
U+10000 到 U+10FFFF 4 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx 表情符号、罕见文字(😀、𝕳、𐐷)

字节模式中的"x"位置保存实际的字符数据。前导位指示字符使用多少字节,允许解码器即使从中间开始读取也能正确同步。

UTF-8 的优势

UTF-8 的主导地位来自几个关键优势:

UTF-8 实践

让我们看看 UTF-8 如何编码不同的字符:

这种可变长度方法意味着主要包含英文文本的文档使用的空间远少于 UTF-16 或 UTF-32,同时在需要时仍支持完整的 Unicode 范围。

专业提示:始终在 HTML 文档中使用 <meta charset="UTF-8"> 指定 UTF-8 编码,并在 HTTP 头中使用 Content-Type: text/html; charset=UTF-8。这可以防止浏览器错误地猜测编码。

UTF-8 vs UTF-16 vs UTF-32:选择正确的编码

虽然 UTF-8 主导 Web 内容,但 UTF-16 和 UTF-32 有其自己的用例。了解差异有助于你为特定需求选择正确的编码。

UTF-16:中间地带

UTF-16 每个字符使用 2 或 4 个字节。BMP 中的字符(U+0000 到 U+FFFF)使用 2 个字节,而 BMP 之外的字符通过称为代理对的机制使用 4 个字节。

优势:

劣势:

UTF-32:固定宽度的简单性

UTF-32 对每个字符使用恰好 4 个字节,使其成为固定宽度编码。每个码位直接映射到 32 位整数。

优势:

劣势:

比较表

特性 UTF-8 UTF-16 UTF-32
每字符字节数 1-4(可变) 2-4(可变) 4(固定)
ASCII 兼容性