unicode - UTF-8编码为什么要前缀10?
问题描述
据我所知,UTF-8 是一种可变长度编码,即一个字符可以表示为 1 个字节、2 个字节、3 个字节或 4 个字节。
例如,Unicode 字符 U+00A9 = 10101001 在 UTF-8 中编码为
110 00010 10 101001,即0xC2 0xA9
第一个字节中的前缀 110 表示该字符以两个字节存储(因为我在前缀 110 中数了两个 1 直到零)。
以下字节中的前缀以 10 开头
一个 4 字节的 UTF-8 编码看起来像
11110 xxx 10 xxxxxx 10 xxxxxx 10 xxxxxx
前缀 11110(四个一和零)表示四个字节,依此类推。
现在我的问题:
为什么在后面的字节中使用前缀 10?这样的前缀有什么好处?如果我写以下字节中没有 10 前缀,我可以使用 3*2=6 位以上:
1111 0000 xxxxxxxx xxxxxxxx xxxxxxxx
解决方案
历史上,有很多关于 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 进行了修改,使其位效率低于之前的提议,但至关重要的是,它可以自我同步,让阅读器从任何地方开始并立即检测字节序列边界。
正如其他人提到的,新编码最明显的优势是自同步。它允许读者轻松找到字符边界,因此可以快速跳过任何丢弃的字节,并且在给定字符串中的任何字节索引的情况下也可以立即找到当前/上一个/下一个字符。如果索引字节以 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 具有这些优点,
推荐阅读
- java - android studio中预热状态的高推理时间
- json - 如何将单独的 ProfilePic 图像 url 添加为 JSON 的参数值,这是 swift 中的参数之一
- object - 1120:访问未定义的属性“selectObject”
- python - ModuleNotFoundError:没有名为“电子商务”的模块
- javascript - Firestore - 按两个不同字段中的两个数组包含查询进行过滤
- javascript - 如何使用时间值对数组进行排序?
- mongodb - 无法将安装在 aws ec2 上的 mongodb 与我的 Windows 机器连接
- html - 填充速记与 4 行代码的 CSS 问题
- amazon-web-services - 具有多个路径部分的 API Gateway REST API 集成请求路径重写
- javascript - 如何从javascript返回数组中的对象数组?