因为没有需要它们的Unicode字符。而且也不能添加它们,因为使用UTF-16代理对它们进行编码是不可能的。
我听过一些理由,但没有一个让我信服。基本上,愚蠢的原因是: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流在“调谐”时或发送者“调谐”时应该抵制错误解读。
11100010 10000010
结尾,你可以确定这个流是不完整的。1110
告诉你:这是一个3字节的单词,但还缺少一个。在建议的“扩展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编码相比,仍然更好。
也许这种推理存在缺陷。这是一种类似的论点:这很难,我将通过尝试并展示陷阱的位置来证明它。
更新:
为了测试一个代码点是否在代理范围内,而不是进行两次关系比较,也可以这样做
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