Unicode 在UTF-16中,代理项对是表示大于2字节的代码点的唯一方法吗?

Unicode 在UTF-16中,代理项对是表示大于2字节的代码点的唯一方法吗?,unicode,utf-16,codepoint,surrogate-pairs,Unicode,Utf 16,Codepoint,Surrogate Pairs,我知道这可能是一个愚蠢的问题,但我需要确定这个问题。例如,我需要知道一种编程语言是否说它的字符串类型使用UTF-16编码,这是否意味着: 它将使用2个字节作为U+0000到U+FFFF范围内的代码点。 对于大于每个代码点的U+FFFF 4字节的代码点,它将使用代理项对。 或者某些编程语言在编码时使用自己的技巧,而不是100%遵循此标准。UTF-16是一种指定的编码,因此如果使用UTF-16,那么您就按照它所说的去做,而不是发明任何自己的技巧 不过,我不会像你那样谈论两个字节。这是一个细节。UTF

我知道这可能是一个愚蠢的问题,但我需要确定这个问题。例如,我需要知道一种编程语言是否说它的字符串类型使用UTF-16编码,这是否意味着:

它将使用2个字节作为U+0000到U+FFFF范围内的代码点。 对于大于每个代码点的U+FFFF 4字节的代码点,它将使用代理项对。
或者某些编程语言在编码时使用自己的技巧,而不是100%遵循此标准。

UTF-16是一种指定的编码,因此如果使用UTF-16,那么您就按照它所说的去做,而不是发明任何自己的技巧

不过,我不会像你那样谈论两个字节。这是一个细节。UTF-16的关键部分是将代码点编码为16位代码单元的序列,并使用成对的代理对大于0xFFFF的代码点进行编码。一个代码单元由两个8位字节组成这一事实是第二层细节,适用于许多系统,但有些系统的字节大小较大,这与此无关,在这种情况下,您可以区分大端和小端表示

但从另一个方向看,绝对没有理由特别使用UTF-16。最终,Unicode文本只是一个值高达221的数字序列,如何表示和序列化这些数字取决于您

我很乐意证明UTF-16是一个历史性的意外事件,如果我们现在必须重做的话,我们可能不会这么做:它是一个可变长度编码,就像UTF-8一样,因此与UTF-32相比,您不会获得随机访问,但它也很冗长。与UTF-8不同,它存在耐久性问题。最糟糕的是,它使用代理项对的实际代码点值将Unicode标准的部分内容与内部表示混淆


在我看来,UTF-16存在的唯一原因是因为在早期人们相信16位对全人类来说永远都足够了,所以UTF-16被设想成是像今天的UTF-32一样的最终解决方案。当这被证明不是真的,替代品和更广泛的范围被附加到UTF-16上。今天,大体上您应该使用UTF-8进行外部序列化,或者使用UTF-32进行内部高效访问。对于纯亚洲文本,可能会有一些额外的原因选择UCS-2。

UTF-16本身是标准的。然而,无论是否声称“支持”UTF-16,字符串基于16位代码单元的大多数语言都可以使用任何代码单元序列,包括无效的代理。例如,这通常是一个可接受的字符串文字:

"x \uDC00 y \uD800 z"
通常,只有当您尝试将其写入另一种编码时,才会出现错误

Python的可选编码/解码选项ProjecteScape使用这些无效的代理将表示单个字节0x80–0xFF的令牌走私到独立的代理代码单元U+DC80–U+DCFF中,从而生成这样的字符串。这通常只在内部使用,因此您不太可能在文件或网络中遇到它;而且它只适用于UTF-16,因为Python的str数据类型基于16位代码单元,这是在3.0和3.3之间的“窄”构建上

我不知道UTF-16的任何其他常用扩展/变体