【发布时间】:2017-11-21 03:59:57
【问题描述】:
出于好奇,我想知道为什么例如带有代码点 322 的字符“ł”在十进制 197:130 中具有 UTF8 二进制表示 197:130 而不是其实际二进制表示 00000001:01000010 在十进制1:66?
【问题讨论】:
标签: unicode
出于好奇,我想知道为什么例如带有代码点 322 的字符“ł”在十进制 197:130 中具有 UTF8 二进制表示 197:130 而不是其实际二进制表示 00000001:01000010 在十进制1:66?
【问题讨论】:
标签: unicode
UTF-8 将 U+0000..U+007F 范围内的 Unicode 代码点编码为单个字节。 U+0080..U+07FF 范围内的码点使用 2 个字节,U+0800..U+FFFF 范围内的码点使用 3 个字节,U+10000..U+10FFFF 范围内的码点使用 4 个字节字节。
当代码点需要两个字节时,则第一个字节以位模式110开始;剩下的 5 位是 Unicode 代码点的高 5 位。连续字节以位模式 10 开始;剩下的 6 位是 Unicode 码位的低 6 位。
您正在查看 ł U+0142 带有笔划的拉丁小写字母 L(十进制 322)。表示十六进制 142 的位模式为:
00000001 01000010
用冒号标记的UTF-8子字段分组,即:
00000:001 01:000010
所以 UTF-8 编码是:
110:00101 10:000010
11000101 10000010
0xC5 0x82
197 130
相同的基本思想适用于 3 字节和 4 字节编码——你砍掉每个连续字节的 6 位,并将前导位与适当的标记位组合起来(1110 表示 3 字节;11110 表示 4 字节——那里与完整字符中的字节数一样多的前导 1 位)。现在还有很多其他规则对你来说并不重要。例如,您永远不会在 UTF-8(或 UTF-32,来吧)中编码 UTF-16 高代理 (U+D800..U+DBFF) 或低代理 (U+DC00..UDFFF)。您永远不会编码非最小序列(因此尽管字节 0xC0 0x80 可用于编码 U+0000,但这是无效的)。这些规则的一个后果是字节 0xC0 和 0xC1 在 UTF-8 中永远无效(0xF5..0xFF 也不是)。
【讨论】:
UTF8 旨在与 7 位 ASCII 兼容。
为了实现这一点,UTF8 编码字节序列中的最高有效位字节用于指示字节是否是多字节编码代码点的一部分。如果设置了 MSB,则该字节是对单个代码点进行编码的 2 个或更多字节序列的一部分。如果 MSB 未设置,则该字节编码范围为 0..127 的代码点。
因此,在 UTF8 中,字节序列 [1][66] 分别代表两个代码点 1 和 66,因为在任何一个字节中都没有设置 MSB (=0)。
此外,代码点#322必须使用在每个字节中设置 MSB (=1) 的字节序列进行编码。
UTF8 encoding are quite a bit more complex 的确切详细信息,但有许多资源可以了解这些详细信息。
【讨论】:
11000101:10000010“翻译”成322来表示“ł”