复合字符和代理对之间的区别

Sac*_*nth 5 unicode utf-16 surrogate-pairs

在Unicode中,复合字符和代理对之间有什么区别?

对我来说,他们听起来像是类似的东西 - 代表一个角色的两个角色.这两个概念的区别是什么?

Ker*_* SB 17

代理对是Unicode中的一个奇怪的疣.

Unicode本身只不过是数字意义的抽象赋值.这就是编码.大写字母A,希腊交替末端-Σ,克林贡闭合支架-2等目前,数字至多约2 21是可用的,尽管不是全部都在使用.在Unicode的上下文中,每个数字都被称为代码点.

但是,Unicode套件作为一个整体不仅包含此编码.它还包含序列化 代码点的技术.这基本上只是序列化无符号整数的练习.指定了三个子技术:UTF-32,UTF-8和UTF-16.

UTF-32简单地将每个代码点表示为32位无符号整数.这很简单.存在两种变体,分别用于大端和小端.每个32位序列化整数称为此格式的代码单元,这是一种固定宽度格式(每个代码单元一个代码点).

UTF-8是一种聪明的多字节格式,其中代码点占用1到6个8位字节.这种格式非常便携,因为它没有订购问题,因为它非常紧凑,适用于英语,近英语和计算机代码.UTF-8的代码单位是一个字节,这是一种可变宽度格式(每个代码点1-6个代码单元).

最后,有UTF-16:最初,人们认为Unicode只能使用2 16个数字,所以这最初被认为是固定宽度,具有16位代码单元.然而,它最终变得清晰,我们需要更大的数字.因此,UTF-16现在也是一种可变宽度格式,但实现这种方式的方法是,某些16位代码单元充当指示器,它们是两个单元对(代理对)的一部分.但是,为了简化检测这些对的方式,而不是像UTF-8那样使用一些外部包络格式,代理人使用的实际16位值被故意泄漏回Unicode编码并且不在编码范围内. - 也就是说,代理值0xD800到0xDFFF 不是有效的Unicode代码点.

因此,总而言之,代理是强制Unicode的序列化格式回到编码中的结果,并且扭曲了编码的设计以适应序列化格式.这可能是一次不幸的历史性事故,回想起来有点毫无意义和难看,但这就是我们拥有的和我们需要的东西.


另一方面,复合字符是更高级别的东西:它们是由多个Unicode代码点组成的可视单元("字形").有时人们将代码点本身称为"字符",但这有点误导,因为字符应该是字形,并且它们可以由几个组件组成(例如基本字母加变音符号和修饰符).

  • 代理值是有效的代码点(它们不是字符),请参阅http://www.unicode.org/faq/utf_bom.html#utf16-2 (2认同)
  • 优秀的描述!UTF-16 既不紧凑,也不固定长度,也不兼容任何东西 - 只是 IT 历史上的一个重大意外。 (2认同)

che*_*ner 6

复合字符的一个例子是 Unicode U+0039, É. 它应该与分解的对 U+0045E和 U+0301(组合重音符号)显示相同。这与用于实际存储字符的任何字节编码无关;它只是使用 Unicode 表示相同图形字符的两种不同方式。

代理对特定于 UTF-16,它使用两个 16 位值来表示大于 U+FFFF 的单个 Unicode 代码点(这显然不能适合单个 16 位值)。例如(来自维基百科文章),代码点 U+1D11E 被序列化为两个 16 位值 0xD834 和 0xDD1E。(用于表示它们的实际字节序列将取决于您使用的是大端还是小端版本的 UTF-16。)

  • 一个常见的例子:文本以具有“É”字形但没有 U+0301 字形的字体呈现。另一个例子:显示引擎执行简单的组合,将变音符号放在一个固定的位置,而不读取基本字符度量(或者引擎做了,但度量是错误的)。 (2认同)