代理对是否只能表示UTF-16中大于2个字节的代码点?

时间:2014-12-10 08:54:42

标签: unicode utf-16 codepoint surrogate-pairs

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

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

2 个答案:

答案 0 :(得分:3)

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

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

但是从另一个方向来看,你应该特别使用UTF-16绝对没有理由。最终,Unicode文本只是一个数字序列(值最多为2 21 ),并由您决定如何表示和序列化这些数字。

我很高兴地说UTF-16是一个历史性的事故,如果我们现在必须重做一切,我们可能不会做的事情:它是一个可变长度编码,就像UTF-8一样,所以你没有随机访问,而不是UTF-32,但它也很冗长。与UTF-8不同,它会遇到字符串问题。最糟糕的是,它通过使用代理对的实际代码点值将Unicode标准的一部分与内部表示混淆。

我认为UTF-16存在的唯一原因是因为在某些早期人们认为16位对于全人类来说永远是足够的,因此UTF-16被设想为最终解决方案(如UTF) -32今天)。当事实证明不是真的时,代理人和更广泛的范围被加到了UTF-16上。今天,您应该使用UTF-8进行外部序列化,或者使用UTF-32进行内部高效访问。 (对于纯亚洲文本,可能有更喜欢UCS-2的原因。)

答案 1 :(得分:0)

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

"x \uDC00 y \uD800 z"

通常只有在尝试将其写入另一种编码时才会出错。

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

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