上一篇《字元編碼發展史5 — UTF-16和UTF-32》我們講解了UTF-16和UTF-32編碼。本篇我們將繼續講解字元編碼中的位元組序標記(BOM)。
2.3. 第三個階段 國際化
2.3.2. Unicode的編碼方式
2.3.2.5. BOM
1. 什麼是BOM?
BOM是Byte 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-8
和UTF-8 BOM
。我們以UTF-8 BOM
儲存時,檔案的開頭三個位元組是0xEF 0xBB 0xBF
,這就是UTF-8 BOM
的標識。
記事本儲存的編碼格式
在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,未來還會折騰更多東西,不死不休。
感謝大家的關注,期待與你一起成長。