据我所知,Unicode UTF-8是可变长度编码。即一个角色 可以用1字节,2字节,3字节或4字节表示。
例如,Unicode字符U + 00A9 = 10101001在UTF-8中编码为
110 00010 10 101001,即0xC2 0xA9
第一个字节中的前缀110表示该字符存储有两个字节(因为我在前缀110中算两个,直到为零)。
以下字节的前缀以10开头
4字节UTF-8编码看起来像
11110 xxx 10 xxxxxx 10 xxxxxx 10 xxxxxx
前缀11110(四个1和零)表示四个字节,依此类推。
现在我的问题:
为什么在随后的字节中使用前缀10??如果在以下字节中没有10前缀,那么我可以使用3 * 2 = 6位来写:
1111 <0000> xxxxxxxx xxxxxxxx xxxxxxxx
答案 0 :(得分:3)
所有多字节字符的后续字节均以二进制10开头,以表示它们是后续字节。
如果传输的某些部分损坏和/或丢失,则允许重新同步。例如,如果缺少多字节序列的第一个字节,您仍然可以找出下一个字符的起始位置。
如果后续字节可以采用任何值,则将无法将后续字节与单字节编码字符区分开。
答案 1 :(得分:2)
从历史上看,有许多关于UTF-8编码的建议。其中一个在接下来的字节中不使用前缀,另一个名为FSS-UTF的情况下使用前缀1
Number First Last
of bytes code point code point
1 U+0000 U+007F 0xxxxxxx
2 U+0080 U+07FF 110xxxxx 10xxxxxx
3 U+0800 U+FFFF 1110xxxx 10xxxxxx 10xxxxxx
4 U+10000 U+1FFFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
5 U+200000 U+3FFFFFF 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
6 U+4000000 U+7FFFFFFF 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
但是最终选择了使用前缀10
的新编码
贝尔实验室的Plan 9操作系统小组的肯·汤普森(Ken Thompson)进行了一项修改,使其比特效率比以前的提议要低一些,但至关重要的是,它可以自我同步,使阅读器可以从任何地方启动并立即检测字节序列边界
新编码最明显的优势是self-synchronization,正如其他人提到的那样。它使读者可以轻松地找到字符边界,因此可以快速跳过任何丢弃的字节,并且给定字符串中的任何字节索引,也可以立即找到当前/上一个/下一个字符。如果索引的字节以10开头,则只是一个中间字节,只需向前或向后查找周围字符的开头;否则,如果它以0或11开头,则为字节序列的开始
该属性非常重要,因为在设计错误的编码中,如Shift-JIS不能进行自同步的情况下,读者必须维护一个字符偏移量表,否则必须从头开始重新解析数组以编辑串。在DOS/V for Japanese(使用Shift-JIS)中,可能由于未使用表而导致内存有限,因此,每次按 Backspace 时,操作系统都需要从头开始重申知道哪个字符被删除。无法像UTF-8那样获得前一个字符的长度
UTF-8的前缀性质还允许旧的C字符串搜索功能无需任何修改即可工作,因为搜索字符串的字节序列永远不会出现在另一个有效UTF-8字节的中间顺序。在Shift-JIS或其他非自同步编码中,您需要专门的搜索功能,因为起始字节可以是另一个字符的中间字节
UTF-16也具有上述一些优势
由于高替代(0xD800–0xDBFF),低替代(0xDC00–0xDFFF)和有效BMP字符(0x0000–0xD7FF,0xE000–0xFFFF)的范围是不相交的,因此替代不能匹配BMP字符,或两个相邻代码单元看起来像合法的代理对。这极大地简化了搜索。这也意味着UTF-16在16位字上进行自我同步:无需检查较早的代码单元就可以确定代码单元是否以字符开头(即,代码单元的类型可以通过其值的范围来确定。下降)。 UTF-8具有这些优点,但是许多早期的多字节编码方案(例如Shift JIS和其他亚洲多字节编码)不允许明确的搜索,并且只能通过从字符串开头(UTF)重新解析来进行同步如果丢失一个字节或遍历从一个随机字节开始,则-16不能自同步。
答案 2 :(得分:0)
我不确定肯·汤普森(Ken Thompson)是否公开陈述了他的理由,但是有一个简单的解释。
UTF-8旨在与ASCII向后兼容。因此,所有单字节UTF-8字符均以0开头。
它本可以设计得尽可能紧凑,即以10xxxxxx作为两个字节序列的前缀,而所有八个位都可以用作连续字节。但是,正式而言,Unicode永远不需要UTF-8现在提供的所有代码点,如果文本文件的磁盘空间很重要,则用户将对其进行压缩。
因此,使算法检测UTF-8尽可能容易是一个更高优先级的设计目标,以便尽可能多的应用程序可以透明地支持它。几乎没有任何其他编码的文档会偶然地看起来像UTF-8 mojibake(但请参阅“布什隐藏事实”。)但是,这不允许太慢地降低解码速度。
因此,连续字节的前缀与初始字节的前缀不同。这些都是高阶位,因此在任何处理器上,区分它们都很简单。前缀的选择也属于一个简单的逻辑序列:单个前导1表示一个字节单位,两个表示两个字节序列的开头,三个表示三字节序列的开头,或者四个表示a的开头。四字节序列。无表示根本没有连续字节。如果必须扩展UTF-8,则继续这种模式将是微不足道的。