Skip to content

搞英语 → 看世界

翻译英文优质信息和名人推特

Menu
  • 首页
  • 作者列表
  • 独立博客
  • 专业媒体
  • 名人推特
  • 邮件列表
  • 关于本站
Menu

RFC 9839 和糟糕的 Unicode

Posted on 2025-08-23

Feed.png

Unicode 很好。如果您正在设计包含文本字段的数据结构或协议,它们应该包含以 UTF-8 编码的 Unicode 字符。不过,还有一个问题:“哪些Unicode 字符?” 答案是“不是全部,请排除一些。”

这个问题一直存在,所以我和 Paul Hoffman 一起向 IETF 提交了一份独立草案,现在(我说的“现在”指的是“两年后”),它已经以RFC 9839 的形式发布。它解释了哪些字符是不合适的,以及为什么,然后提供了三个可能不太合适的子集,你可以参考一下。这里先介绍一下背景知识,但是……

请

如果您正在开发包含文本字段的新项目,请阅读 RFC。它只有十页,而且包含了所有 IETF 样板文件。它是专门为软件和网络人员编写的。

确凿证据

9839 关注的问题是“有问题的字符”,所以让我们先举一个痛苦的例子来解释一下它的含义。假设你正在设计一个使用 JSON 的协议,并且你的一个构造函数包含一个username段。假设你收到这条消息(我省略了所有非username名字段)。这是一个完全合法的 JSON 文本:

 {      “用户名” : “\u0000\u0089\uDEAD\uD9BF\uDFFF”  }

解压所有 JSON 转义乱码后发现, username段的值包含四个标识 Unicode 字符的数字“代码点”:

  1. 第一个代码点是零,用 Unicode 术语来说U+0000 。在人类可读的文本中,它没有任何意义,但它会干扰某些编程语言的运行。

  2. 接下来是 Unicode U+0089 ,正式名称为“带对齐的字符制表符”。它是 Unicode 所称的C1 控制码,继承自 ISO/IEC 6429:1992,采纳自ECMA 48 (1991),后者称之为“HTJ”,其含义为: HTJ 使活动字段(呈现组件中包含活动呈现位置的字段)的内容前移,使其结束于下一个字符制表符停止位之前的字符位置。活动呈现位置移动到下一个字符制表符停止位。移位字符串开头之前的字符位置将被置于擦除状态。

    祝你好运。

  3. 第三个码位U+DEAD ,用 Unicode 术语来说,是“非成对代理”。要理解它,你必须了解 Unicode 中那个被人诟病的UTF-16编码是如何运作的。我建议你还是别费心了。

    你需要知道的是,代理只有在 UTF-16 编码文本中成对出现时才有意义。实际上,网络上不存在这样的文本,因此没有理由容忍数据中存在代理。事实上,UTF-8 规范规定,你不能使用 UTF-8 编码代理。但真正的问题是,不同编程语言的不同库在遇到这种恶臭的“闯入者”时,处理方式并不总是相同的。

  4. 最后, \uD9BF\uDFFF是代码点U+7FFFF的 JSON 格式。Unicode 中有一个类别叫做“非字符”,其中包含几十个代码点,由于各种原因,有些是好的,有些则不代表任何内容,因此不能在网络上互换。U U+7FFFF就是其中之一。

示例中的四个代码点显然都是有问题的。刚刚发布的 RFC 9839 正式定义了“有问题”的概念,并提供了易于引用的语言,说明了哪些有问题的类型需要从文本字段中排除。如果你打算使用 JSON,那么你应该这样做。

不要责怪道格

我指的是 Doug Crockford,JSON 的发明者。如果他(或者我,或者任何认真的人)在 Unicode 已经成熟的现在发明 JSON,他会对它的字符库更加挑剔。话虽如此,我们永远只能使用 JSON 的原样,所以我们需要一个好的方法来指定哪些有问题的字符需要排除,即使 JSON 允许这些字符。

精确

你可能会好奇,为什么 IETF 要等到 2025 年才提供针对“糟糕的 Unicode”问题的帮助。它并没有这样做;这里有RFC 8264 : PRECIS 框架:应用协议中国际化字符串的准备、执行和比较;第一个 PRECIS 前身发布于 2002 年。8264 长达 43 页,对比 9839 更多的潜在“糟糕的 Unicode”问题进行了非常详尽的讨论。

与 9839 一样,PRECIS 指定了 Unicode 字符集的子集,并更进一步,提供了定义更多内容的机制。

话虽如此,PRECIS 似乎并没有被那些定义新数据结构和协议的人广泛使用。我个人认为,有两个问题导致它难以采用。首先,它庞大而复杂,包含许多可变部分,需要仔细研究才能理解。开发人员(有充分的理由)很懒惰。

其次,使用 PRECIS 会将你绑定到特定版本的 Unicode。具体来说,它禁止使用(近百万个)未分配的代码点。由于 Unicode 的每个版本都包含新的代码点分配,这意味着如果发送方和接收方想要实现可靠的互操作行为,他们需要就他们将要使用的 Unicode 版本达成一致。这使得编写用于各种不同应用程序的通用代码变得困难。

我个人认为,人们想要使用的 Unicode 的唯一版本是“尽可能新”,这样他们就可以确信拥有所有最新的表情符号。

无论如何,9839 比 PRECIS 更简单、更笨拙。但我认为有些人会觉得它有用,而且现在 IETF 也同意这一点。

源代码

我编写了一个 Go 语言的小库,用于根据 9839 指定的三个子集分别验证传入的文本字段,具体见这里。我不敢说它是最优的,但它确实经过了充分的测试。

目前它还没有版本号或发布版本,我会等到一些人有机会发现我可能犯的任何愚蠢错误。

细节

以下是存在问题的 Unicode 代码点、数据格式和标准的简要概述。

问题类别被排除?
代理人 旧版控件 非角色
CBOR 是的 不 不
I-JSON 是的 不 是的
JSON 不 不 不
Protobufs 不 不 不
托米 是的 不 不
XML 是的 部分 [1] 部分 [2]
YAML 是的 大多 [3] 部分 [2]
RFC 9839 子集
标量 是的 不 不
XML 是的 部分的 部分的
可分配项 是的 是的 是的

笔记:

[1] XML 允许 C1 控件。

[2] XML 和 YAML 不排除基本多语言窗格之外的非字符。

[3] YAML 排除了所有遗留控件,除了几乎无害的U+0085 (IBM 大型机文档中使用的\n的另一个版本)。

谢谢!

9839 并非我的个人作品。它得到了众多睿智且见多识广人士的深入讨论和改进,经过 15 次修改后,最终发布的版本比我的初稿有了显著的提升。我衷心感谢我的联合编辑 Paul Hoffman 以及 RFC 致谢部分中提到的所有人。

关于个人提交

9339 是我向 IETF 提交的第二个“单独提交”的 RFC(另一个是RFC 7725 ,它注册了 HTTP 451 状态码)。虽然决定某个东西值得标准化并最终实现它是一件好事,但这确实需要大量工作。有些工作甚至很烦人。

我曾以工作组成员、工作组主席和工作组规范编辑的身份参与过其他工作,我可以权威地报告,通过工作组以传统方式创建 RFC 更容易、更好。

我不太愿意劝别人不要追随我的脚步,但在这种情况下,我认为这是正确的建议。

原文: https://www.tbray.org/ongoing/When/202x/2025/08/14/RFC9839

本站文章系自动翻译,站长会周期检查,如果有不当内容,请点此留言,非常感谢。
  • Abhinav
  • Abigail Pain
  • Adam Fortuna
  • Alberto Gallego
  • Alex Wlchan
  • Answer.AI
  • Arne Bahlo
  • Ben Carlson
  • Ben Kuhn
  • Bert Hubert
  • Big Technology
  • Bits about Money
  • Brandon Skerritt
  • Brian Krebs
  • ByteByteGo
  • Chip Huyen
  • Chips and Cheese
  • Christopher Butler
  • Colin Percival
  • Cool Infographics
  • Dan Sinker
  • David Walsh
  • Dmitry Dolzhenko
  • Dustin Curtis
  • eighty twenty
  • Elad Gil
  • Ellie Huxtable
  • Ethan Dalool
  • Ethan Marcotte
  • Exponential View
  • FAIL Blog
  • Founder Weekly
  • Geoffrey Huntley
  • Geoffrey Litt
  • Greg Mankiw
  • HeardThat Blog
  • Henrique Dias
  • Herman Martinus
  • Hypercritical
  • IEEE Spectrum
  • Investment Talk
  • Jaz
  • Jeff Geerling
  • Jonas Hietala
  • Josh Comeau
  • Lenny Rachitsky
  • Li Haoyi
  • Liz Danzico
  • Lou Plummer
  • Luke Wroblewski
  • Maggie Appleton
  • Matt Baer
  • Matt Stoller
  • Matthias Endler
  • Mert Bulan
  • Mind Matters
  • Mostly metrics
  • Naval Ravikant
  • News Letter
  • NextDraft
  • Non_Interactive
  • Not Boring
  • One Useful Thing
  • Phil Eaton
  • Product Market Fit
  • Readwise
  • ReedyBear
  • Robert Heaton
  • Rohit Patel
  • Ruben Schade
  • Sage Economics
  • Sam Altman
  • Sam Rose
  • selfh.st
  • Shtetl-Optimized
  • Simon schreibt
  • Slashdot
  • Small Good Things
  • Steph Ango
  • Stephen Wolfram
  • Steve Blank
  • Taylor Troesh
  • Telegram Blog
  • The Macro Compass
  • The Pomp Letter
  • thesephist
  • Thinking Deep & Wide
  • Tim Kellogg
  • Understanding AI
  • Wes Kao
  • 英文媒体
  • 英文推特
  • 英文独立博客
©2025 搞英语 → 看世界 | Design: Newspaperly WordPress Theme