在Unicode中,复合字符和代理项对之间的区别是什么?
对我而言,他们听起来像是类似的东西 - 代表一个角色的两个角色。这两个概念的区别是什么?
答案 0 :(得分: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代码点组成的可视单元(“字形”)。有时人们将代码点本身称为“字符”,但这有点误导,因为字符应该是字形,并且它们可以由几个组件组成(例如基本字母加变音符号和修饰符)。
答案 1 :(得分:4)
复合字符的示例是Unicode U + 0039,É
。它应该与分解的对U + 0045 E
和U + 0301(组合的急性重音字符)相同地显示。这与用于实际存储字符的任何字节编码无关;它只是使用Unicode表示相同图形字符的两种不同方式。
代理对特定于UTF-16,它使用两个16位值来表示大于U + FFFF的单个Unicode代码点(显然不能适合单个16位值)。例如(来自Wikipedia article),代码点U + 1D11E被序列化为两个16位值0xD834和0xDD1E。 (用于表示它们的实际字节序列取决于您是使用UTF-16的big endian还是little endian版本。)