D91 UTF-16编码形式:分配每个的Unicode编码形式 U+0000..U+D7FF 和 U+E000..U+FFFF 范围内的 Unicode 标量值 到具有相同数值的单个无符号 16 位代码单元 Unicode 标量值,并且 分配每个 Unicode 标量值 在 U+10000..U+10FFFF 范围内到代理对.
术语“标量值”是指 unicode 代码点,即必须通过不同编码形式(UTF-16 等)编码为特定字节序列的抽象概念的范围。因此,看来这个摘录要点是考虑到并非所有代码点都可以容纳在一个 UTF-16 代码单元(两个字节)中,有些代码点应该编码成一对代码单元 - 4 个字节(称为“代理对”)。
但是,术语“标量值”的定义如下:
D76 Unicode 标量值: 除高代理项之外的任何 Unicode 代码点 和低代理代码点。
等等... Unicode 有代理代码点吗? UTF-16 可以使用 4 个字节来表示标量点,这是什么原因呢?谁能解释一下原理以及 UTF-16 如何使用这个代码点?
是的,Unicode 保留代理代码点的范围:
Unicode 保留这些范围,因为这些 16 位值用于代理对中,并且不能为它们分配其他符号。代理对是两个 16 位值,它们对 U+FFFF 以上的代码点进行编码,但不适合单个 16 位值。
只是为了最终澄清。
U+000E
代码点将被编码为 0x000E
,U+000F
为 0x000F
,依此类推。0x0000
- 0xFFFF
范围仅允许 65 536 个可能的值)。我们可能会使用两个 16 位字(4 个字节)来表示超出这些边界的代码点(实际上,我的误解是为什么 UTF-16 不这样做)。然而,这种方法会导致无法解码某些值。例如,如果我们将 U+10000
代码点编码为 0x00010000
,解释器究竟应该如何解码这种表示:作为两个不同的连续代码点,U+0001
和 U+0000
,或者作为单个代码点,U+10000
?U+10000
- U+10FFFF
范围(顺便说一下,有 1 048 576 个代码点)进行编码,那么我们应该首先从单字节范围中分离出 1 024 + 1 024 = 2 048 个值(出于这些目的,规范选择了 0xD800
- 0xDFFF
)。当解释器遇到 0xD800
- 0xDBFF
值时,它知道这里没有编码隐含的“成熟”代码点(根据规范,没有标量值),然后它应该读取另外 16 位获取 0xDC00
- 0xDFFF
范围内的值,并最终得出 U+10000
- U+10FFF
代码点中的哪一个是用这 4 个字节编码的。请注意,此方案可以编码 1 024 * 1 024 = 1 048 576 个代码点(这正是我们需要的数量)。U+0000
到 0x10FFFF
的代码点空间。那么 U+D800
- U+DFFF
子空间在其中被称为 High Surrogate Area 和 U+DC00
- U+DFFF
Low Surrogate Area。由于这些代码points的值与UTF-16代码units的值相匹配(=代码点的具体表示),因此该包含可以被视为UTF-16遗迹:高代理和低代理代码点指定用于 UTF-16 字符编码形式的代理代码单元。他们是 未分配给任何抽象字符。 [规格]