UTF-8直接存储代码点的理由是什么?

时间:2019-08-09 13:26:39

标签: utf-8 character-encoding history

UTF-8将代码点的有效位存储在代码单元的低位

U+0000-U+007F       0xxxxxxx
U+0080-U+07FF       110xxxxx    10xxxxxx
U+0800-U+FFFF       1110xxxx    10xxxxxx    10xxxxxx
U+10000-U+10FFFF    11110xxx    10xxxxxx    10xxxxxx    10xxxxxx

这要求解码器检查over long sequences(像C0 80而不是00),并且还减少了可编码的代码点数,直至固定字节数。如果它使用相同的编码,但是这样映射代码点

  • 前128个代码点(U + 0000-U + 007F):1个字节
  • 接下来的2048个代码点(U + 0080-U + 087F):2个字节。例如。 C0 81:U + 0081
  • 下一个65536个代码点(U + 0880-U + 1087F):3个字节。例如。 E0 B0 B1:U + 0881
  • 接下来的131072个代码点(U + 10880-U + 10FFFF,最多U + 20880):4个字节。例如。 F0 B0 B0 B1:U + 10881

(即该值将偏移量编码为范围的开头)

然后可以使用较短的序列编码更多的字符。解码的速度也可能更快,因为它只需要添加一个常量即可,这通常比检查超长代码点的分支要便宜。实际上,如果我们从映射中删除代理对范围,则可以将2048个字符压缩成3个字节

那为什么UTF-8那样存储代码点呢?

1 个答案:

答案 0 :(得分:1)

“ placemat”轶事中有充分的论据,其中讲述了当Unicode专家(实际上是X / Open的某人)与他们联系以进行审查时,Ken Thompson和Rob Pike如何在一家餐馆中提高了该餐垫的规格。规范草案。

http://doc.cat-v.org/bell_labs/utf-8_history包含Rob Pike本人的叙述,他,Ken Thompson和X / Open人之间有通信。它称此愿望为早期草案中缺少的关键部分之一:

  

  同步中途采集的字节流,且少于一个   同步之前消耗了字符

换句话说,当您查看设置了高位的字节时,可以仅从该字节值就知道您是否处于UTF-8序列的中间,如果是,则需要多远快退到多字节编码字符的开头。

完整的故事值得一读,因此我在这里仅作简要总结。以下是Wikipedia article's history section.

的节的简化版
  

到1992年初,人们一直在寻求对多字节字符集进行良好的字节流编码的方法。 ISO 10646标准草案包含一个不需要的附件,称为UTF-1,该附件提供了其32位代码点的字节流编码。这种编码在性能方面还不能令人满意,其中最大的问题可能是ASCII与非ASCII之间没有清晰的分隔...

     

1992年7月,X / Open委员会XoJIG寻求更好的编码。 Unix系统实验室的Dave Prosser提出了一个具有更快的实现特性的提议,并介绍了7位ASCII字符只能代表自己的改进。所有多字节序列将仅包含设置高位的字节。 ...

     

1992年8月,该提案由IBM X / Open代表分发给有关各方。 Bell Labs的Plan 9操作系统小组的Ken Thompson进行了修改,使其位效率比以前的建议低一些,但至关重要的是,它可以自我同步,使阅读器可以从任何地方启动并立即检测字节序列边界。它还放弃了使用偏差,而是增加了规则,即只允许最短的编码。紧凑性带来的额外损失相对来说是微不足道的,但是读者现在必须注意无效编码,以避免可靠性,尤其是安全性问题。 1992年9月2日,汤普森(Thompson)与罗​​伯·派克(Rob Pike)在新泽西州一家小餐馆的餐垫上概述了汤普森的设计。在接下来的几天里,Pike和Thompson实施了它并更新了Plan 9以在整个过程中使用它,然后将其成功传达给X / Open,后者将其接受为FSS-UTF的规范。