字元編碼發展史6 — BOM位元組序標記

陌尘(MoChen)發表於2024-10-10

上一篇《字元編碼發展史5 — UTF-16和UTF-32》我們講解了UTF-16和UTF-32編碼。本篇我們將繼續講解字元編碼中的位元組序標記(BOM)。

2.3. 第三個階段 國際化

2.3.2. Unicode的編碼方式

2.3.2.5. BOM

1. 什麼是BOM?

BOMByte Order Mark的縮寫,翻譯成中文是:位元組序標記,主要用於文字編碼中,表示資料儲存的位元組順序。

前面我們講到UTF-16和UTF-32是存在大小端的位元組序問題的。以UTF-16為例,要識別一個檔案是以大端(Big-endian)位元組序還是小端(Little-endian)位元組序儲存的,就需要有一個標識來進行標記。業界統一的做法是:在檔案的開頭加入一個特殊的字元來表示,該字元就是U+FEFF,因此BOM也可認為是該字元(U+FEFF)的一個別名。

  • 在UTF-16BE檔案中,BOM是0xFE 0xFF
  • 在UTF-16LE檔案中,BOM是0xFF 0xFE
  • 在UTF-32BE檔案中,BOM是0x00 0x00 0xFE 0xFF
  • 在UTF-32LE檔案中,BOM是0xFF 0xFE 0x00 0x00
2. Windows下為什麼會有UTF-8和UTF-8BOM?

UTF-8編碼本身並不存在位元組序的問題,所以UTF-8編碼理論上是不需要位元組序的。

熟悉Windows的同學應該知道,Windows的“記事本”在儲存時可以選擇編碼方式,編碼方式的下拉框裡有UTF-8UTF-8 BOM。我們以UTF-8 BOM儲存時,檔案的開頭三個位元組是0xEF 0xBB 0xBF,這就是UTF-8 BOM的標識。

file
記事本儲存的編碼格式

file
在VSCode中以Hex Editor方式開啟

為什麼Windows下為什麼有UTF-8 BOM,這個已經無從查證,很可能是Windows歷史發展的遺留產物。猜測可能是為了明確標識某個檔案是由UTF-8編碼方式儲存的。因為字元編碼的發展歷史來看,UTF-8的出現晚於ANSI系列編碼,Windows早期為了適配各個國家的語言,系統預設編碼採用了ANSI系列的編碼,美國和西歐地區預設編碼是ISO-8859-1,中國大陸預設編碼編碼是GBK。如:在Windows下有一個XXX.txt的純文字檔案,如果不加位元組序標記則無法知道這個檔案是UTF-8編碼的還是GBK編碼的。如果UTF-8編碼的檔案預設加上BOM標識,則可以透過這個標識來區分是UTF-8還是GBK編碼。

在Windows11下,我們看到新建的.txt檔案,windows的記事本會預設以UTF-8(無BOM)來儲存了,說明Windows作業系統新的版本也預設使用UTF-8編碼了。

就跨平臺的相容性而言,UTF-8會比UTF-8 BOM更好。

3. 不同編碼的位元組序總結
編碼方式 BOM位元組序標識
UTF-8
UTF-8 BOM 0xEF 0xBB 0xBF
UTF-16BE 0xFE 0xFF
UTF-16LE 0xFF 0xFE
UTF-32BE 0x00 0x00 0xFE 0xFF
UTF-32LE 0xFF 0xFE 0x00 0x00

《字元編碼發展史》系列已完結

歷史文章推薦:

字元編碼發展史5 — UTF-16和UTF-32

字元編碼發展史4 — Unicode與UTF-8

字元編碼發展史3 — GB2312/Big5/GBK/GB18030

字元編碼發展史2 — ISO-8859-N

字元編碼發展史1 — ASCII和EASCII


大家好,我是陌塵。

IT從業10年+, 北漂過也深漂過,目前暫定居於杭州,未來不知還會飄向何方。

搞了8年C++,也幹過2年前端;用Python寫過書,也玩過一點PHP,未來還會折騰更多東西,不死不休。

感謝大家的關注,期待與你一起成長。



【SunLogging】
字元編碼發展史6 — BOM位元組序標記
掃碼二維碼,關注微信公眾號,閱讀更多精彩內容

相關文章