【问题标题】:Isn’t on big endian machines UTF-8's byte order different than on little endian machines? So why then doesn’t UTF-8 require a BOM?大端机器上 UTF-8 的字节顺序与小端机器上的字节顺序不同吗?那么为什么 UTF-8 不需要 BOM 呢?
【发布时间】:2010-09-30 18:33:49
【问题描述】:

UTF-8 可以包含 BOM。然而,它 没有区别 字节流的字节序。 UTF-8 始终具有相同的字节顺序。

如果Utf-8 将所有代码点存储在一个字节中,那么为什么字节序不发挥任何作用以及为什么不需要BOM 是有道理的。但是由于代码点 128 及以上使用 2、3 和最多 6 个字节存储,这意味着它们在大端机器上的字节顺序与在小端机器上不同,所以我们怎么能声称 Utf-8 总是具有相同的字节顺序?

谢谢

编辑:

UTF-8 是面向字节的

我知道如果两个字节 UTF-8 字符 C 由字节 B1 和 B2 组成(其中 B1 是第一个字节,B2 是最后一个字节),那么UTF-8 这两个字节是总是以相同的顺序写入(因此,如果这个字符被写入小端机器LEM 上的文件,B1 将是第一个,B2 最后一个。类似地,如果C 被写入大端机器上的文件机器BEMB1 仍将是第一个,B2 仍将是最后一个)。

但是当C 被写入LEM 上的文件F 时会发生什么,但是我们将F 复制到BEM 并尝试在那里读取它?由于BEM 自动交换字节(B1 现在是最后一个字节,B2 第一个字节),读取F 的应用程序(在BEM 上运行)如何知道F 是否是在BEM 上创建的,因此是两个的顺序字节没有被交换或者F 是否从LEM 转移,在这种情况下BEM 自动交换了字节?

我希望这个问题有意义

编辑 2:

响应您的编辑:big-endian 如果你问,机器不会交换字节 他们一次读取一个字节。

a) 哦,所以即使字符 C 是 2 个字节长,读取 F 的应用程序(驻留在 BEM 上)也会读入内存一次只有一个字节(因此它将首先读入内存B1,然后才读入B2

b)

在 UTF-8 中,您决定如何处理 字节基于其高位

假设文件F有两个后续字符CC1(其中C由字节组成B1B2C1 有字节 B3B4B5 )。阅读 F 的应用程序如何仅通过检查每个字节的高位来知道哪些字节属于一起(例如,它如何确定 B1B2 合起来应该代表一个字符而不是 B1,*B2* 和 B3)?

如果你相信你看到 不同的东西,请编辑你的 问题并包括

我不是这么说的。我只是不明白发生了什么

c) 为什么 Utf-16 和 Utf-32 也不是面向字节的?

【问题讨论】:

  • “面向字节”意味着您一次读取一个字节,并根据该字节决定要做什么。在 UTF-8 中,您根据字节的高位来决定如何处理它。相比之下,在 UTF-16 和 UTF-32 中,您一次处理多个字节,并且必须将它们组织成单词。
  • 响应您的编辑:如果您要求大端机器一次读取一个字节,则它们不会交换字节。如果您认为您看到了不同的东西,请编辑您的问题并包括 (1) 源和目标计算机和操作系统,(2) 您复制文件(从您的终端复制粘贴,不要解释),以及 (3) 证明文件已更改(例如,通过使用 od 显示字节级输出)。哦,请使用code以外的一些亮点。
  • 来自 UTF-8 FAQ (unicode.org/faq/utf_bom.html): 问:UTF-8 的定义是什么?答:UTF-8 是 Unicode 的面向字节的编码形式。 (后面有更多详细信息的链接)。
  • @mlvljr 你的意思是……?
  • UTF-8 不是由字节序参数化的,但多字节序列必须具有某种排序约定的直觉是一个很好的直觉。 UTF-8 多字节序列中直接包含了一种大字节序。如果将 UTF-8 字节序列的所有有效位从左到右粘贴在一起并用前导零填充,则会得到代码点的大端表示(如果填充为 32 位,则为 UTF-32)。假设可以使用小端序,但它会非常尴尬。

标签: unicode utf-8


【解决方案1】:

对于大于字节的字/整数,大端和小端机器上的字节顺序不同。

例如在大端机器上,一个 2 字节的短整数在第一个字节中存储 8 个最高有效位,在第二个字节中存储 8 个最低有效位。在 little-endian 机器上,8 个最高有效位在第二个字节,8 个最低有效位在第一个字节。

因此,如果您将这样一个短整数的内存内容直接写入文件/网络,短整数内的字节顺序将根据字节序而有所不同。

UTF-8 是面向字节的,因此不存在字节序问题。第一个字节总是第一个字节,第二个字节总是第二个字节等等。不管字节顺序。

【讨论】:

  • 你能看看我的编辑吗,因为还有一些我不太明白的地方
  • 在处理字节时,BEM 和 LEM 都不会交换任何字节。如果您将超过 1 个字节作为更大的类型读取,它们将被交换,例如2 个字节作为 short 或 4 个字节作为 int 然后你必须关心哪个字节在整数中的位置
  • 字节根本不会“自动”交换。根据字节顺序,它们具有不同的含义(如果是较大整数的一部分),但没有交换。
  • 我们可以说,即使是 Little-Endian 机器也必须将 UTF-8 文件视为“Big Endian”?因为它必须读取第一个字节,并且基于该字节,如果读取的字符是 2 个字节,它将读取下一个字节。但这实际上是 Big Endian.. 所以我认为我们可以说 UTF-8 在某种程度上强制 Big Endian,不是吗?
  • @KorayTugay:不,你不能这么说。显然你不明白字节序实际上是什么。你所说的大端也适用于小端。如果你有一个多字节整数,你仍然需要读取所有字节来完成整数。决定整数值的是字节顺序的解释。
【解决方案2】:

回答 c):UTF-16 和 UTF-32 将字符表示为 16 位或 32 位字,因此它们不是面向字节的。

对于 UTF-8,最小单位是一个字节,因此它是面向字节的。该算法一次读取或写入一个字节。一个字节在所有机器上的表示方式都相同。

对于 UTF-16,最小单位是 16 位字,对于 UTF-32,最小单位是 32 位字。该算法一次读取或写入一个字(2 个字节或 4 个字节)。在 big-endian 和 little-endian 机器上,每个 word 中的字节顺序是不同的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-07-13
    • 1970-01-01
    • 2016-04-25
    • 1970-01-01
    • 2015-11-30
    • 1970-01-01
    • 2021-01-26
    相关资源
    最近更新 更多