欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

字节序Endian与字节序标记BOM详解

发布时间:2023/12/20 编程问答 68 豆豆
生活随笔 收集整理的这篇文章主要介绍了 字节序Endian与字节序标记BOM详解 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

问题引入

问:UTF-8 和 UTF-8-BOM 有啥区别?

我们用 Python 演示一下,带与不带 BOM 的字符串有啥区别。

if __name__ == '__main__':str = '你好啊树哥'print('str:', str)str_encode_utf8 = str.encode('utf-8')print('str_encode_utf8:', str_encode_utf8)str_encode_utf8_bom = str.encode('utf-8-sig')print('str_encode_utf8_bom:', str_encode_utf8_bom)

输出结果显示,带 BOM 的比不带的文本在开头多了 ef bb bf 几个字节,为什么是这样?它有什么用呢?

str: 你好啊树哥 str_encode_utf8: b'\xe4\xbd\xa0\xe5\xa5\xbd\xe5\x95\x8a\xe6\xa0\x91\xe5\x93\xa5' str_encode_utf8_bom: b'\xef\xbb\xbf\xe4\xbd\xa0\xe5\xa5\xbd\xe5\x95\x8a\xe6\xa0\x91\xe5\x93\xa5'

BOM 全称 Byte Order Mark,字节顺序标记的意思,今天我们就来详细聊聊它。

字节序

字节序(Endian),就是字节顺序(Byte-Order),还叫端序或尾序(Endianness)。描述的是计算机对 多字节数据 存储和传输时字节的顺序。因为单字节的数据只需要读取一个字节,没有字节序说法。

字节序分为两种排列模式,分别是大端字节序和小端字节序。

  • 大端(Big-endian):高位字节数据存放在内存低地址处,低位字节数据存放在内存高地址处。大端模式比较符合人类的阅读习惯,也这是人类读写数值的方式。
  • 小端(Little-endian):高位字节数据存放在内存高地址处,低位字节数据存放在内存低地址处。由于计算机内存数据处理是从低位开始的,因为小端模式更加符合计算机的处理方式。

例如有 0x1234abcd 将它写入到以 0x0000 开始的内存中。

内存地址0x00000x00010x00020x0003
Big-endian0x120x340xab0xcd
Little-endian0xcd0xab0x340x12

计算机默认都是从低位开始读,所以计算机内部处理都是小端字节序。但人类习惯读写大端字节序,所以除了计算机的内部处理,其他的应用场合几乎都是大端字节序,比如网络传输和文件存储。

  • 主机字节序,Host Byte Order, HBO。指机器的字节序,有大端和小端模式,由机器的CPU处理器的处理决定,小端模式较为常见。
  • 网络字节序,Network Byte Order, NBO。是TCP/IP中规定好的一种数据表示格式,网络字节序采用 Big Endian 排列按照从高到低的顺序存储,在网络上使用统一的网络字节顺序可以避免兼容性问题。TCP/IP中规定好了一种数据表示格式,与具体的CPU类型、操作系统等无关,从而保证数据在不同主机之间传输时能够被正确解释。

字节序标记

BOM,全称 Byte Order Mark,字节顺序标记。出现在文本文件头部,用于标识文件是采用哪种格式的编码。

由于 FEFF 和 FFFE 在 UCS 编码表中不存在(也就是说它无实际意义),因此在字节流传输过程中可以利用它们打头来说明字节序。

  • 如果接收者收到以 FEFF 开通的字节流,就表明这是 Big-Endian 的;
  • 如果收到 FFFE 就表明这个字节流是 Little- Endian 的。

像 FEFF 和 FFFE 这种就称作 Zero Width No-Break Space,翻译过来就是 零宽无间断间隔 ,这个字符就是所谓的 BOM。下面是不同编码的字节顺序标记表示。

编码表示
UTF-8EF BB BF
UTF-16 (大端序)FE FF
UTF-16(小端序)FF FE
UTF-32 (大端序)00 00 FE FF
UTF-32 (小端序)FF FE 00 00

总结几点注意事项。

  • UTF-8 本身不需要 BOM ,但可以使用它。UTF-8 始终是相同的字节顺序,BOM 仅用于表明编码方式。如果接收者收到以 EF BB BF 开头的字节流,就知道这是 UTF-8编码了。
  • 以前字符 U+FEFF 出现在开头就是标识该字节流的字节序,如果出现在字节流的中间则表达零宽度非换行空格的意义,用户看起来就是一个空格。从 Unicode 3.2 开始,U+FEFF 只能出现在字节流的开头用于标识字节序。取而代之的是,使用 U+2060 来表达零宽度无断空白。
  • 刚刚说到的 U+FEFF 是代码点,抽象性质的。而 EF BB BF ,FE FF,00 00 FE FF 则是在不同编码方案下的具体表现形式。这是概念性的问题。

参考

参考了

[1]. Endian
https://www.jianshu.com/p/a348f8fc9fc9
[2]. BOM (字节顺序标记(ByteOrderMark))
https://baike.baidu.com/item/BOM/2790364?fr=aladdin
[3]. 字节顺序标记(BOM)详解
https://blog.csdn.net/gufenchen/article/details/90552774
[4]. 「带 BOM 的 UTF-8」和「无 BOM 的 UTF-8」有什么区别?网页代码一般使用哪个?
https://www.zhihu.com/question/20167122

总结

以上是生活随笔为你收集整理的字节序Endian与字节序标记BOM详解的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。