字节序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 開始的內存中。
| Big-endian | 0x12 | 0x34 | 0xab | 0xcd |
| Little-endian | 0xcd | 0xab | 0x34 | 0x12 |
計算機默認都是從低位開始讀,所以計算機內部處理都是小端字節序。但人類習慣讀寫大端字節序,所以除了計算機的內部處理,其他的應用場合幾乎都是大端字節序,比如網絡傳輸和文件存儲。
- 主機字節序,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-8 | EF 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详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Tensorflow-制作与使用tfre
- 下一篇: 认知天性个人笔记6