为什么UTF-8中没有5字节和6字节的编码点?

5
为什么没有5字节或6字节的代码点?我知道它们曾经存在,直到2003年被移除。但我找不到为什么被移除的原因。
维基百科关于UTF-8的页面说:

在2003年11月,UTF-8受限于RFC 3629以匹配UTF-16字符编码的约束:明确禁止对应于高代理和低代理字符的代码点,这导致三字节序列减少超过3%,而在U+10FFFF处结束则删除了超过48%的四字节序列和所有五字节和六字节序列。

但我不明白为什么这很重要。
3个回答

9

因为没有需要它们的Unicode字符。而且也不能添加它们,因为使用UTF-16代理对它们进行编码是不可能的。


所以如果我理解正确的话,它们现在只是不需要的,当需要向Unicode添加更多字符时,UTF-16将被扩展以支持它们(我不知道,是6字节的UTF-16代码点吗?),而UTF-8将重新启用第5和第6字节? - graywolf
2
@Paladin:不,Unicode的人们得出结论认为这种需求不会出现。 - MSalters
Unicode还有很长的路要走,才能达到UTF-16编码的1112064个代码点的极限。UTF-8最初支持5字节和6字节的编码,但后来被限制为最多4字节,以与UTF-16完全兼容。如果Unicode超过了UTF-16的处理范围,就必须创建一个新的UTF(如果不只是使用UTF-32),因此在那时可能会取消UTF-8的4字节限制。 - Remy Lebeau
2
根据Wikipedia的说法:“目前,约有10%的潜在空间被使用。此外,为每个当前和古代书写系统(脚本)暂定映射了字符范围,Unicode联盟已经能够识别出来。即使发现了具有数万个字符的以前未知的脚本,也不太可能在不久的将来达到1,114,112个代码点的限制。Unicode联盟已经声明,这个限制将永远不会改变。” - Remy Lebeau

2

我听过一些理由,但没有一个让我信服。基本上,愚蠢的原因是:UTF-16在UTF-8之前被指定,并且当时认为为字符提供20位存储空间(产生2²⁰+2¹⁶个字符,减去一些非字符和代理项以进行管理)足够了。

UTF-8和UTF-16已经是可变长度编码,就像你所说的UTF-8一样,可以轻松扩展(使用5和6字节的单词)。将UTF-32扩展以包括21到31位很容易(32可能会有符号问题),但使其变长完全破坏了UTF-32的用例。

扩展UTF-16很困难,但我会尝试。看看UTF-8在2字节序列中的作用:初始的110yyyyy充当高代理项,10zzzzzz充当低代理项。对于UTF-16,将其翻转并重新使用高代理项作为“初始代理项”,低代理项作为“继续代理项”。因此,基本上,您可以拥有多个低代理项。

然而,有一个问题:Unicode流在“调谐”时或发送者“调谐”时应该抵制错误解读。

  • 在UTF-8中,如果你读取一串字节并以11100010 10000010结尾,你可以确定这个流是不完整的。1110告诉你:这是一个3字节的单词,但还缺少一个。在建议的“扩展UTF-16”中,没有类似的情况。
  • 在UTF-16中,如果你读取一串字节并以高代理结尾,你可以确定这个流是不完整的。

使用U+10FFFE作为单个UTF-32编码的公告可以解决“调谐”问题。如果流在U+10FFFE之后停止,你就知道你丢失了一些内容,对于不完整的UTF-32也是如此。如果它在U+10FFFE的中间停止,那么它缺少一个低代理。但是,这种方法不能解决“调谐”到UTF-32编码可能会误导你的问题。

可以利用所谓的非字符(最著名的是字节顺序标记的反转)在第16平面的末尾:使用现有代理将U+10FFFE和U+10FFFF编码为3或4字节序列来宣布。这非常浪费:32位仅用于公告,另外使用48或64位进行实际编码。但是,与使用U+10FFFE和U+10FFFF 围绕 单个UTF-32编码相比,仍然更好。

也许这种推理存在缺陷。这是一种类似的论点:这很难,我将通过尝试并展示陷阱的位置来证明它。


1

更新:

为了测试一个代码点是否在代理范围内,而不是进行两次关系比较,也可以这样做

 floor( N / 2048 ) == 27

(这与4^5 * 54-or-55相同,术语重新排列)

===========================================

现在为4^8 + 4^10个代码点(CP)分配了空间,即1,114,112个,但只有四分之一到三分之一的空间被分配给任何东西。

因此,除非在很短的时间内突然需要添加另外750k CP,否则UTF-8的4字节应该足够使用多年。

**仅个人偏好

  • 4^8 + 4^10

除了清晰简洁外,它还通过UTF-8字节数清晰地划分了CP:

 4 ^  8 =    65,536 = all CPs for 1-, 2-, or 3-bytes UTF-8
 4 ^ 10 = 1,048,576 = all CPs for            4-bytes UTF-8

不要使用不雅的东西,例如

 2^16 *  17

或者更糟糕的是,

 32^4 + 16^4

*** 不相关的旁注:*我设法想出了用于UTF-16代理项起始点的最干净的公式三元组为:: *

 4^5 * 54 = 55,296 = 0x D800 = High - surrogates
 4^5 * 55 = 56,320 = 0x DC00 = Low  - surrogates
 4^5 * 56 = 57,344 = 0x E000 = just beyond the upper-boundary of 0x DFFF

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接