代码之家  ›  专栏  ›  技术社区  ›  FrozenHeart

为什么我们必须在UTF-16和UTF-32编码的情况下指定BOM

  •  0
  • FrozenHeart  · 技术社区  · 8 年前

    我不太理解UTF编码和BOM背后的原理。

    如果计算机已经知道如何将多字节数据类型(例如,大小为4字节的整数)组合成一个变量,那么在UTF-16和UTF-32中使用BOM有什么意义?那么为什么我们需要为这些编码显式指定它呢?

    为什么我们不需要为UTF-8指定它?Unicode标准说它是“面向字节的”,但即使如此,我们也需要知道它是否是编码代码点的第一个字节。还是在每个字符的前/后位指定?

    3 回复  |  直到 8 年前
        1
  •  4
  •   csharpfolk    8 年前

    UTF-16是两个字节宽,让我们称之为字节 B0|B1 . 假设我们有字母“a”,这是逻辑数字0x0061。不幸的是,不同的计算机架构以不同的方式将这个数字存储在内存中,在x86平台上,较低的字节首先存储(在较低的内存地址),因此“a”将存储为 00|61 。在PowerPC上,这将存储为 61|00 因此,这两种架构被称为小端和大端。

    为了加快字符串处理速度,库通常以本机顺序存储两个字节的字符(大端或小端)。交换字节太贵了。

    现在假设PowerPC上有人将字符串写入文件,库将写入字节 00|61 ,现在x86上有人想读取这个字节,但这意味着 00|61 或者可能 61|00 ? 我们可以将特殊序列放在字符串的开头,这样任何人都可以知道用于保存字符串的字节顺序,并正确处理它(在endian之间转换字符串是一项成本高昂的操作,但大多数时候x86字符串将在x86 arch上读取,PowerPC字符串将在PowerPC机器上读取)

    对于UTF-8,这是一个不同的故事,UTF-8使用单顺序并将字符长度编码为第一个字符的第一位模式。UTF-8编码在 Wikipedia 一般来说 设计 为了避免结尾的问题

        2
  •  2
  •   John Sensebe    8 年前

    不同的架构可以对事物进行不同的编码。一个系统可能会将0x12345678写为0x12 0x34 0x56 0x78,另一个系统则可能会将其写为0x78 0x56 0x34 0x12。了解源系统是如何写东西的,这一点很重要。字节是读取或写入的最小单位,因此如果一种格式是逐字节写入的,就没有问题,就像没有系统在读取另一个ASCII文件时遇到问题一样。

    UTF-16 BOM, U+FEFF 将根据系统写入0xFE 0xFF或0xFF 0xFE。知道这些字节的写入顺序可以告诉读者字节在文件其余部分的写入顺序。UTF-32使用相同的BOM字符,用16个零位填充,但其用途相同。

    另一方面,UTF-8被设计为一次读取一个字节。因此,即使在处理多字节字符时,所有系统上的顺序都是相同的。

        3
  •  1
  •   tripleee Suman    8 年前

    UTF-16和UTF-32编码不指定字节顺序。在8位字节的流中,代码点U+FEFF可以用UTF-16编码为字节FE,FF(大端)或FF,FE(小端)。流编写器显然无法知道流将在哪里结束(文件、网络套接字、本地程序?)因此,您在开头放一个BOM表,以帮助读者确定编码和字节顺序变量。

    UTF-8没有这种模糊性,因为它从一开始就是面向字节的编码。用UTF-8编码这个码点的唯一方法是以这个精确的顺序使用字节EF、BB、BF。(方便的是,序列化的第一个字节中的高位也显示了序列将占用多少字节。)