UTF-8 编码为什么前缀为 10?

kno*_*dge 8 unicode encoding character utf-8

据我所知,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(四个一和零)表示四个字节,依此类推。

现在我的问题:

为什么在以下字节中使用前缀 10?这样的前缀有什么好处?如果在以下字节中没有 10 前缀,我可以多使用 3*2=6 位,如果我写:

1111 0000 xxxxxxxx xxxxxxxx xxxxxxxx

phu*_*clv 6

历史上有很多关于 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
Run Code Online (Sandbox Code Playgroud)

然而最后使用的前缀的新的编码10选择

贝尔实验室 Plan 9 操作系统小组的 Ken Thompson 进行了修改,使其比之前的提案在位效率上有所降低,但至关重要的是允许它自同步,让阅读器从任何地方开始并立即检测字节序列边界。

https://en.wikipedia.org/wiki/UTF-8#History

正如其他人提到的,新编码最明显的优点是自同步。它允许读者轻松找到字符边界,因此可以快速跳过任何丢弃的字节,并且还可以在给定字符串中的任何字节索引的情况下立即找到当前/上一个/下一个字符。如果索引字节以 10 开头,则只是一个中间字节,只需向后或向前查找周围字符的开头即可;否则,如果它以 0 或 11 开头,则它是字节序列的开始

这个属性非常重要,因为在像Shift-JIS这样没有自同步的糟糕设计的编码中,阅读器必须维护一个字符偏移表,或者它必须从头开始重新解析数组以编辑字符串。在用于日语的 DOS/V(使用 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 具有这些优点,

https://en.wikipedia.org/wiki/UTF-16#Description


Joa*_*uer 5

多字节字符的所有后续字节都以二进制 10 开头,表示它们是后续字节。

如果传输的某些部分损坏和/或丢失,这允许重新同步。例如,如果多字节序列的第一个字节丢失,您仍然可以找出下一个字符的开始位置。

如果后续字节可以取任何值,则无法将后续字节与单字节编码字符区分开来。

  • 即使没有丢失字节,这也适用于在 UTF-8 字符串中查找。给定任何随机字节,您可以查看其前缀并立即知道它是编码序列的第一个字节还是继续字节,在后一种情况下,您可以向后或向前查找前缀,直到找到没有延续前缀。因此*每个字节*的前缀需要采用可预测的模式。这正是 UTF-8 定义的 (2认同)