为什么utf-16只支持2^20码位?

Why does utf-16 only support 2^20 code points?

好吧,我现在开始研究unicode,我有几个疑惑,此时我正在学习什么是平面,我看到平面是一组2 ^ 16个代码点,并且utf-16 编码支持从 0 到 16 枚举的 17 个计划,那么我的问题如下,如果 utf-16 最多支持 32 位,因为实际上它最多只编码 2^20 个代码点? 20从哪里来?我知道如果代码点需要超过 2 个字节,utf-16 使用两个 16 位单元,但是这如何适应所有这些,最后的问题是这个 2^20 来自哪里而不是 2^32 ?谢谢,:)

看看代理对如何编码字符 U >= 0x10000:

U' = yyyyyyyyyyxxxxxxxxxx  // U - 0x10000
W1 = 110110yyyyyyyyyy      // 0xD800 + yyyyyyyyyy
W2 = 110111xxxxxxxxxx      // 0xDC00 + xxxxxxxxxx

(source)

如您所见,从 2x16 代理项对的 32 位中,2x6 = 12 位“仅”用于传达信息,即这确实是一个代理项对(而不仅仅是两个具有值 < 0x10000)。这为您留下 32 - 12 = 20 位来存储 U'。

(从技术上讲,您还有一些 U < 0x10000 的值,其中一些值再次保留给低代理和高代理,这意味着您最终 略高于 2考虑到 UTF-16 支持的最高可能代码点是 U+10FFFF 而不是 2^20 = [=14=,可以使用 UTF-16 编码的 ^20 个代码点(但仍远低于 2^21) ].)

original form of Unicode 仅支持 64k 代码点(16 位)。目的是支持所有 常用的现代 字符,而 64k 确实足够了(是的,甚至包括中文)。作为介绍说明(强调我的):

Completeness. The coded character set would be large enough to encompass all characters that were likely to be used in general text interchange.

但 Unicode 逐渐涵盖几乎所有人类书写,包括历史和 lesser-used 书写系统,而 64k 字符太小而无法处理。 (Unicode 14 有大约 145k 个字符。)正如 Unicode 2.0 介绍所说(再次强调我的):

The Unicode Standard, Version 2.0 contains 38,885 characters from the world's scripts. These characters are more than sufficient not only for modern communication, but also for the classical forms of many languages.

在 Unicode 1.x 中,典型的编码是 UCS-2,它只是定义 code-point 的一个简单的 16 位数字。当他们决定需要更多代码时(在 Unicode 1.1 时间框架内),只分配了大约 34k 个代码点。

最初的想法是创建一个 32 位编码 (UCS-4),它可以用一位 left-over 编码 231 个值,但这会编码的大小加倍,浪费了很多 space,并且不会向后兼容 UCS-2。

因此他们决定为 Unicode 2.0 发明一个系统 backward-compatible,其中包含所有已定义的 UCS-2 代码点,但这允许他们扩展得更大。这就是为什么他们发明了代理对系统( 解释得很好)。这创建了完全取代 UCS-2 的 UTF-16 编码。

Unicode 2.0 简介中解释了各个领域需要多少 space 的完整思考:

There are over 18,000 unassigned code positions that are available for for future allocation. This number far exceeds anticipated character coding requirements for modern and most archaic characters.

One million additional characters are accessible through the surrogate extension mechanism.... This number far exceeds anticipated encoding requirements for all world characters and symbols.

目标是在基本多语言平面 (BMP) 中保留“通用”字符,并将 lesser-used 个字符放入代理扩展区域。

代理系统“浪费”了大量可用于真实字符的代码点。您可以想象用一个更简单的系统替换它,该系统只有一个“下一个字符在代理 space 中”代码点。但这会在字节序列之间产生歧义。你不能只搜索 0x0041 来找到字母 A。你必须向后扫描以确保它不是代理字符,这使得某些类型的问题变得更加困难。

该设计选择非常可靠。 20 年来,随着越来越多晦涩难懂的文字和角色的稳步增加,我们使用的可用文字和字符还不到 15% space。我们绝对不需要另外 10 位。