什么是UTF-8:定义、操作、错误和用途

最后更新: 25月2025
  • UTF-8 使用 1-4 个字节对 Unicode 点进行编码,与 ASCII 兼容并且适用于任何语言。
  • 自同步和验证:0/110/1110/11110 模式可防止重叠并更容易检测错误。
  • Web 和系统:元字符集、大量支持和在 Windows/macOS/Linux 上的轻松转换。

UTF-8 和 Unicode 编码

如果您今天阅读这篇文章时没有看到任何奇怪的符号,这都要归功于UTF-8编码。这种编码方式使得字母、重音符号、技术符号,甚至表情符号,都能在任何现代浏览器、操作系统或电子邮件客户端中以相同的方式显示。它是网络上应用最广泛的标准,也是我们所知的数字通信的基础。

当设备显示文本时,它实际上是在处理数字。这些数字是由Unicode 标准定义的代码点,为了将它们转换为可以在网络上传输或保存到文件中的字节,我们需要进行一种转换:UTF-8编码。接下来,您将了解 UTF-8 编码是什么、它的工作原理、它成为标准的原因、它的优势和局限性,以及如何避免常见错误。

什么是 UTF-8?

UTF-8(8 位 Unicode 转换格式)是一种将 Unicode 代码点转换为字节序列的方法。它的主要特点是使用可变长度:有些字符占用 1 个字节,而有些字符则需要 2、3 或 4 个字节。这使得它能够表示包含简单拉丁字符的紧凑文本,但也可以表示 Unicode 字符集中的任何字符。

它与ASCII完全兼容:前 128 个字符(U+0000 到 U+007F)使用与 7 位 ASCII 相同的单个字节进行编码。这简化了从旧系统的过渡,并解释了它在互联网、电子邮件和 IETF 协议中取得巨大成功的原因。

UTF-8 的突出特点在于其稳健性:它包含同步位,可以可靠地识别每个符号的起始位置。这种自同步特性使得检测序列是否“看起来像”UTF-8 变得容易,这在工具和解析器中非常有用。

Unicode:一切的基础

Unicode 是一种通用标准,它为每个字符分配一个唯一的数字,无论语言、平台或应用程序如何。这个数字称为代码点,通常以十六进制格式 U+XXXX(或根据需要添加更多位数)书写。

例如: 大写字母“A”的 U+0041在 HTML 中我们也可以将其称为 A. 你的计算机不会将 A “视为” 一个字母,而是数字 65,然后编码(例如 UTF-8)决定如何用字节表示该数字。

如果你想查看 Unicode 如何转换为电脑上的字符,在 Windows 系统中,你可以按住 Alt 键,然后在数字键盘上输入十进制数字代码:例如,Alt+65 会返回“A”(参见完整的 Alt 代码列表)。这是一个经典的快捷方式,可以显示你看到的字符背后的代码。

一点历史:UTF-8 是如何诞生的

UTF-8 编码由 Ken Thompson 在 Rob Pike 的指导下于 1992 年 9 月 2 日设计完成。他们将其应用于贝尔实验室的 Plan 9 操作系统,并在1993 年 1 月于圣地亚哥举行的 USENIX 大会上正式发布。在由X/Open 联合国际化组织 (XOJIG)赞助的标准化过程中, UTF-8曾使用过 FSS/UTF 和 UTF-2 等名称,最终统一命名为 UTF-8。

该设计解决了以往通用编码方案中存在的诸多实际问题:ASCII 兼容性、自同步、无字节重叠以及易于错误检测。这种平衡使其成为网络的实际标准

  PC 端口的类型:它们是什么、它们有什么用途以及如何选择

UTF-8 的工作原理

UTF-8 根据编码字符所需的字节数对字符进行分组。字节数完全取决于 Unicode 代码点,并遵循指示序列长度的位模式。

  • 1 个字节(U+0000 至 U+007F):ASCII 字符。格式: 0xxxxxxx。最高有效位为 0,即 保证与 ASCII 直接兼容.
  • 2 个字节(U+0080 至 U+07FF): 格式 110yyyyy 10xxxxxx. 它适用于大多数带有变音符号的欧洲字母以及其他字母,例如希腊文、西里尔文、希伯来文或阿拉伯文。.
  • 3 个字节(U+0800 至 U+FFFF): 格式 1110zzzz 10yyyyyy 10xxxxxx. 包含多语言基本计划(BMP),带有 CJK(中文、日语、韩语)、技术符号和最常用的字符。
  • 4 个字节(U+10000 至 U+10FFFF): 格式 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx. 代表补充平面:高级数学符号、历史著作、不太常见的表意符号等。

自同步的关键在于头部位:ASCII 码为 0;两个字节为 110;三个字节为 1110;四个字节为 11110。续行字节总是以 10 开头。因此,续行字节永远不会作为起始字节出现,并且有效的序列永远不会是更长序列的子串(非重叠原则)。

与 UTF-16 和代理对的等效性

UTF-16 以 16 位为单位表示 BMP 代码点 并指向 U+FFFF 以上位置 替代对 在范围中 D800–DFFF。 相反 UTF-8 始终编码真实代码点,而不是 UTF-16 单位,这避免了与替代品混淆。

历史上,一些草案允许UTF-8 使用5 或 6 个字节来覆盖更广泛的范围,但Unicode 和 RFC 3629 将 UTF-8 限制为最多 4 个字节。ISO/IEC 曾考虑过更宽的选项,但这些选项并未纳入当前的标准。

实际例子:ñ

字符“ñ”的代码点为U+00F1,它位于双字节范围内。按照该模式,它被编码为 110xxxxx 10xxxxxx. 其 UTF-8 表示形式为 0xC3 0xB1解码是相反的过程:读取有用的位并重建原始代码点。

UTF-8 的优点和局限性

主要优势

  • ASCII 支持:ASCII 文本在 UTF-8 中有效,无需更改。
  • 普遍:可以表示任何 Unicode 字符,包括技术符号和表情符号。
  • 拉丁文本的效率:当使用 1 个字节表示 ASCII 时, 与 UTF-16 相比节省空间 在许多西方语言中。
  • 自同步和检测:位模式允许 检测字符开头 并轻松验证序列。

局限性和权衡取舍

  • CJK 文本比 UTF-16 文本占用更多空间,其中许多字符适合 2 个固定字节。
  • 计算成本:长度可变,某些操作(例如“转到字符 n”) 需要从头开始并且某些任务在 UTF-16/UTF-32 中可能会更快。

UTF-8 中的 BOM(字节顺序标记)

UTF-8 不需要 BOM 因为字节顺序不会改变值的含义(最小单位是字节)。即便如此, 有一个可选的 BOM,字符 U+FEFF 编码为 EF BB BF 在文件或流的开头,可用于指示“这是 Unicode/UTF-8”。

  树莓派上 Home Assistant 安装完整指南

最佳实践:如果 BOM 出现在开头,有些系统会接受它,而有些系统则会按字面意思处理。在字符串拼接中,建议移除中间的 BOM。包含 BOM 并非强制性的,而且它在 UTF-8 编码中的作用远不如 UTF-16/UTF-32 编码(在 UTF-16/UTF-32 编码中,BOM 可以标记字节序)

典型的编码错误及其处理方法

一个可靠的 UTF-8 解码器必须能够拒绝格式错误的序列,或者将其替换为 U+FFFD(替换字符),或者标记错误。最常见的错误包括:

  • 截短序列:没有足够连续性的多字节前导字节。
  • 松散的连续字节: 出现 10xxxxxx 没有有效的前导字节。
  • 超长:使用比必要更多的字节进行编码;例如,尝试使用 2 个字节对 ASCII 进行编码(0xC0 y 0xC1 无效).
  • 禁止的长度: 开始建议 5 或 6 个字节(0xF80xFD 无效 使用标准 UTF-8 编码)。
  • 超出Unicode范围的值: 不支持高于 U+10FFFF 的值;某些值(0xF50xF7 作为开端)是无效的。
  • UTF-16 代理对: D800–DFFF 不是有效的代码点 以 Unicode 表示;它们不应该以 UTF-8 编码出现。

当您在屏幕上看到字符“�”时,很可能是由于编码不匹配或文件以不同的代码页保存造成的。解决方法是强制使用端到端的 UTF-8 编码(文件、服务器、数据库、HTTP 标头)。

网络和电子邮件中的 UTF-8

一个 HTML 页面只需要声明一种编码。为了兼容性和覆盖范围,推荐使用 UTF-8 编码。请尽快在页面头部添加以下 meta 标签:

<meta charset="UTF-8">

将其放在 `<head>` 标签的开头,以便浏览器在处理文档之前读取它。这可以防止出现不一致和“乱码”。UTF -8 在网络上的普及程度非常高;绝大多数网站都使用它。

在电子邮件领域, UTF-8 编码被互联网邮件联盟 (IMC) 等组织广泛支持和推荐。将电子邮件客户端配置为使用 UTF-8 编码可以减少与使用其他语言的人交换邮件时出现的问题。

UTF-8、UTF-16 和 UTF-32:有什么区别?

UTF-8:采用 8 位单位的可变长度编码;非常适合网页设计,对 ASCII 和西方语言兼容性极佳,并具备出色的错误检测能力。

UTF-16:可变长度编码,以 16 位为单位;对于 U+10000 及以上的字符,使用代理对。当非 ASCII 字符占主导地位时,UTF-16 通常具有优势,并且被许多 API 和平台所采用(例如,Windows 本身就以 UTF-16 编码运行)。

UTF-32:每个字符长度固定为 32 位;索引非常简单,但占用空间较大。它仅适用于处理简便性比文件大小更重要的场景。

不兼容的变体:CESU-8 和“修改版 UTF-8”

CESU-8直接对 UTF-16 单元(包括代理对)进行编码,而不是对码位进行编码,因此对于 U+FFFF 以上的字符,它与标准 UTF-8 有所不同。一些早期的平台曾使用过 CESU-8:Oracle 8 以别名 UTF-8 提供CESU-8,而从 Oracle 9 开始,它又以另一个别名添加了标准 UTF-8。Java和 Tcl在某些情况下也使用过 CESU-8 。

修改后的 UTF-8 编码(例如在 Java 环境中)将空字符 (U+0000) 表示为 0xC0 0x80而不是 0x00。它避免了 C 字符串中的空字节,但并不符合 UTF-8 标准。许多这种“修改版”的实现也符合 CESU-8 标准

  如何根据实际使用情况选择最佳电脑鼠标

Windows 和 API 上的 UTF-8:代码页和转换

Windows 内部以 UTF-16 (WCHAR) 运行,但从 Windows 10 版本 1903 开始​​,你可以 强制使用 UTF-8 作为进程代码页 通过应用程序清单(属性 activeCodePage)。这使得使用“-A” API 的旧代码可以更轻松地通过 UTF-8 运行。

API -A 与 -W-A 取决于 ANSI 代码页 配置(可以是 CP_UTF8),而 -W 他们使用 UTF-16. 为了实现互操作, 的MultiByteToWideChar y 调用WideCharToMultiByte 允许您在 UTF-8 和 UTF-16 之间进行转换; 美国 CP_UTF8 并且,如果适用的话, MB_ERR_INVALID_CHARS 检测输入错误。

真正的兼容性:浏览器和系统

UTF-8编码与现代浏览器(Chrome、Firefox、Safari、Edge、Opera以及最新版本的Internet Explorer)和大多数操作系统(Windows、Linux、macOS、Android、iOS)兼容。除非您使用的是非常老旧的软件,否则应该不会遇到任何问题

如何将文件转换为 UTF-8

在 Windows 系统中(记事本):打开文件,选择“文件 > 另存为…”,然后在“编码”中选择UTF-8。如果想保留原文件,请使用新名称另存为。

在 macOS 系统中(文本编辑):在“文本编辑 > 偏好设置 > 打开与保存”中,保存时选择Unicode (UTF-8)。然后启用该选项导出文件。

在Linux上:您可以使用终端 iconv。 例如: iconv -f <codificación_origen> -t UTF-8 <entrada> -o <salida>. 稍后检查 使用它的应用程序也需要 UTF-8。

如何判断文件是否为 UTF-8 编码?许多现代编辑器会在状态栏中显示相关信息。如果您看到诸如“�”之类的奇怪字符、损坏的重音符号或显示错误的“ñ/ç”,请检查文件编码以及编辑器/服务器/数据库设置

避免意外的良好做法

尽早将 UTF-8 编码声明在 HTML 和 HTTP 头部中。确保整个技术栈(源文件、模板、数据库和连接)的编码一致。避免在同一页面或流程中混用不同的编码,并使用能够验证/规范化输入的工具。

对于集成和 API,始终在标题中指定编码(Content-Type: application/json; charset=UTF-8(例如)。 使用多语言数据进行测试 (重音、CJK、表情符号)在生产之前检测弱点。

UTF-8之所以胜出,是因为它兼顾了兼容性、效率和覆盖范围。无论文本是否包含重音符号、技术符号或非拉丁字母,它都是确保文本在不同文化、系统和应用程序中完整传输的最实用方法。

什么是unicode代码
相关文章:
什么是 Unicode:完整指南、用途和编码