【问题标题】:Regarding unicode characters and their utf8 binary representation关于 unicode 字符及其 utf8 二进制表示
【发布时间】:2017-11-21 03:59:57
【问题描述】:

出于好奇,我想知道为什么例如带有代码点 322 的字符“ł”在十进制 197:130 中具有 UTF8 二进制表示 197:130 而不是其实际二进制表示 00000001:01000010 在十进制1:66?

【问题讨论】:

标签: unicode


【解决方案1】:

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 也不是)。

【讨论】:

    【解决方案2】:

    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来表示“ł”
    • Methinks ASCII 是 7 位代码,而不是 127 位代码。它有 128 个字符,值 0..127 — 这可能是您的“127 位 ASCII”的来源。我一直听说 U+0000 .. U+007F 代码是单字节,不需要连续字节来完成它们。
    • @JonathanLeffler - 哈哈。我觉得你可能是对的。简单的错字 - 很容易纠正。 :)
    • 谢谢;简单的修复确实是简单的修复。我担心您需要更仔细地查看 UTF-8 的编码。您的描述并不完全准确。
    猜你喜欢
    • 1970-01-01
    • 2017-11-10
    • 1970-01-01
    • 1970-01-01
    • 2016-10-05
    • 2021-04-21
    • 1970-01-01
    • 1970-01-01
    • 2015-06-10
    相关资源
    最近更新 更多