为什么Unicode代码点的UTF-8编码不能容纳3个字节

时间:2019-02-20 21:12:28

标签: unicode

Wikipedia

  

Unicode包含1,114,112个代码点,范围从0hex到10FFFFhex

我不知道unicode编码最多可以占用4个字节。 1,114,112个代码点不能舒适地容纳在3个字节中吗?可能是我缺少一些需要4个字节的特殊情况;请举一些具体的例子吗?

3 个答案:

答案 0 :(得分:4)

维基百科关于UTF-8历史的文章说,较早版本的UTF-8允许对21位以上的比特进行编码。这些编码占用了5个甚至6个字节。

很明显,对于人类的剩余时间来说,2 ^ 21个代码点可能就足够了(与5位,6位,7位,8位和16位相同的思维方式),其编码分别为5和完全禁止使用6个字节。保留所有其他编码规则,以实现向后兼容。

因此,Unicode代码点的数字空间现在为0..10FFFF,甚至比21位还少一点。因此,有必要检查一下这21位是否适合3个字节的24位,而不是当前的4个字节。

UTF-8的一个重要属性是,作为多字节编码一部分的每个字节都有其最高位设置。为了区分前导字节和尾随字节,前导字节设置了第二高位,而尾随字节则清除了第二高位。此属性可确保顺序一致。因此,字符可以这样编码:

0xxx_xxxx                        7 bits freely chooseable
110x_xxxx 10xx_xxxx             11 bits freely chooseable
1110_xxxx 10xx_xxxx 10xx_xxxx   16 bits freely chooseable

现在7 + 11 + 16位= 16.04位,比所需的21位短得多。因此,不可能按照当前的UTF-8编码规则使用3个字节来编码所有Unicode代码点。

您可以定义另一种编码,其中每个字节的最高位是连续位:

0xxx_xxxx                        7 bits freely chooseable
1xxx_xxxx 0xxx_xxxx             14 bits freely chooseable
1xxx_xxxx 1xxx_xxxx 0xxx_xxxx   21 bits freely chooseable

现在,您有足够的空间来编码所有21位代码点。但这是一种全新的编码,因此您必须在全球范围内建立这种编码。根据Unicode的经验,大约需要20年。祝你好运。

答案 1 :(得分:2)

“ unicode”不是编码。 Unicode的通用编码为UTF-8,UTF-16和UTF-32。 UTF-8使用1、2、3或4字节序列,下面将进行说明。前导/尾随位序列的开销要求21位值需要4个字节。

UTF-8编码使用以下位模式最多使用4个字节来表示Unicode代码点:

  

1个字节的UTF-8 = 0xxxxxxx bin = 7位= U + 0000至U + 007F
  2字节UTF-8 = 110xxxxx 10xxxxxx bin = 11位= U + 0080至U + 07FF
  3字节UTF-8 = 1110xxxx 10xxxxxx 10xxxxxx bin = 16位= U + 0800至U + FFFF
  4字节UTF-8 = 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx bin = 21位= U + 10000至U + 10FFFF

UTF-8的优点是前导字节是唯一的模式,尾部字节是唯一的模式,可以轻松验证正确的UTF-8序列。

还请注意,对于适合较小序列的Unicode值使用较长的编码是非法的。例如:

  

1100_0001 1000_0001 bin C1 81 hex 编码为U + 0041,但 0100_0001 bin 41 hex )是较短的序列。

参考:https://en.wikipedia.org/wiki/UTF-8

答案 2 :(得分:0)

我扩大我的评论。

Unicode不是编码。拥有unicode代码点的大小没有意义。 Unicode是代码点和语义名称(例如“拉丁文大写字母A”)之间的映射。您可以自由选择自己的编码。

最初,Unicode希望成为适合16位的通用编码(因此,日语/中文统一)。如您所见,它在此目标上失败了。还有第二点(非常重要)是能够转换为Unicode并回传而不会丢失数据(这简化了转换为Unicode的过程:一次,在任何层一次)。

因此,如何扩展Unicode以支持16位以上存在一个问题,但同时又不破坏所有Unicode程序。这个想法是使用代理,所以只知道16位Unicode(UCS-2)的程序仍然可以工作(而BTW python2和Javascript只知道UCS-2,并且它们仍然可以正常工作。该语言不需要知道Unicode代码点可能超过16位。

代理人给出了实际Unicode的上限(所以不等于2的幂)。

后来它被设计为UTF-8。特点(通过设计):与ASCII兼容(在7位字符上),对所有代码点(也> 16位)进行编码,并且蜜蜂能够移至随机位置并在字符开​​始处快速同步。最后一点占用了一些地址空间,因此文本虽然没有尽可能的密集,但是却更加实用(并且可以快速“滚动”文件)。这些额外的数据(用于同步)使得无法使用UTF-8将所有新的Unicode代码点编码为3个字节。

您可以使用UTF-24(请参阅注释),但是您失去了与ASCII兼容的UFT-8优势,但是与UTF-16相比,您通常只有2个字节(而不是4个字节)。

请记住:16位以上的Unicode代码点很少:古老的语言,现有字形的更好表示(语义)或新的表情符号(希望它们不会仅用表情符号填充整个长文本)。因此,尚不需要3字节的实用程序。也许如果外星人来到地球并且我们应该用他们的新语言字符书写,我们将主要使用16位以上的Unicode代码点。我认为不会很快发生。