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

标签 unicode utf-16 codepoint surrogate-pairs

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

  1. 它将使用 U+0000 到 U+FFFF 范围内的 2 个字节作为代码点。
  2. 它将对大于 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 的边缘原因。)

关于unicode - 代理对是表示 UTF-16 中大于 2 个字节的代码点的唯一方法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27396758/

相关文章:

javascript - 如何将 utf-16 缓冲区与字符串进行比较?

c++ - 从 char* 创建 UTF-16 字符串

java - 给定 Unicode 代码点的编号,如何获取该字符的 String 或 CharSequence 对象

perl - 在 Perl 中将 UTF8 字符串转换为数值

php - 是否有易于使用且支持 unicode 的 PHP PDF 库?

python - 使用 lxml.html 的 cssselect 选择 ID 属性中带有冒号的元素

python - 类型错误 : decoding str is not supported (Python 3. 4)

c++ - C++ 中的 Unicode 问题,但不是 C

c++ - 如何将一个字符(ICU4C)Unicode字符串复制到另一个Unicode字符串?