4 回答

TA貢獻1839條經驗 獲得超15個贊
UTF-8 BOM是文本流(EF BB BF)開始時的字節序列,它允許讀者更可靠地猜測文件是在UTF-8中編碼的。
通常,BOM用來表示編碼的endianness,但是由于endianness與UTF-8無關,所以BOM是不必要的。

TA貢獻1859條經驗 獲得超6個贊
UTF-8和BOM-ed UTF-8之間沒有正式區別。 BOM編輯的UTF-8字符串將以下三個字節開始. EF BB BF
如果存在這些字節,則在從文件/流中提取字符串時必須忽略這些字節。
合法 字符串“ain”、“abc” 合法 字符串“abc”
編碼應該是已知的,而不是預言。

TA貢獻1998條經驗 獲得超6個贊
不包含文本的文件不再是空的,因為它們總是包含BOM。 在UTF-8的ASCII子集中保存文本的文件不再是ASCII,因為BOM不是ASCII,這使得一些現有工具崩潰,用戶可能無法替換這些遺留工具。 不可能將多個文件連接在一起,因為現在每個文件在開始時都有一個BOM。
這是不夠的,因為任意字節序列可能會以構成BOM的確切序列開始。 沒有必要,因為您可以像讀取UTF-8一樣讀取字節;如果成功,則定義為有效的UTF-8。

TA貢獻2037條經驗 獲得超6個贊
這是一個古老的問題,有許多好的答案,但有一件事應該補充。
所有的答案都很籠統。我想補充的是BOM使用的例子,它們實際上造成了真正的問題,但是很多人并不知道。
BOM破壞腳本
shell腳本、Perl腳本、Python腳本、Ruby腳本、Node.js腳本或任何需要由解釋器運行的其他可執行文件
#!/bin/sh #!/usr/bin/python #!/usr/local/bin/perl #!/usr/bin/env?node
它告訴系統在調用這樣一個腳本時需要運行哪個解釋器。如果腳本是用UTF-8編碼的,人們可能會在一開始就嘗試包括一個BOM。但實際上“#!”人物不僅僅是人物。他們實際上是幻數它恰好由兩個ASCII字符組成。如果你把一些東西(如BOM)放在這些字符之前,那么文件看起來就像有一個不同的神奇數字,這可能會導致問題。
Shebang字符由擴展的ASCII編碼(包括UTF-8)中相同的兩個字節表示,UTF-8通常用于當前類Unix系統上的腳本和其他文本文件。但是,utf-8文件可能以可選字節順序標記(Bom)開頭;如果“exec”函數專門檢測字節0x23和0x21,則BOM(0xEF 0xBB 0xBF)的存在將阻止腳本解釋器的執行。一些權威機構建議不要在POSIX(類Unix)腳本中使用字節順序標記,[14]正是出于這個原因以及更廣泛的互操作性和哲學考慮。此外,在UTF-8中,字節順序標記是不必要的,因為編碼不存在Endianness問題;它只用于將編碼標識為UTF-8。[強調后加]
BOM在JSON中是非法的
實現不能在JSON文本的開頭添加字節順序標記。
BOM在JSON中是多余的
不僅是非法在JSON中,它也是不需要確定字符編碼,因為有更可靠的方法可以明確地確定任何JSON流中使用的字符編碼和endianness
BOM破壞JSON解析器
不僅是非法在JSON和不需要,實際上破壞所有軟件中顯示的方法來確定編碼。
確定JSON的編碼和endianness,檢查NUL字節的前4個字節:
00?00?00?xx?-?UTF-32BE 00?xx?00?xx?-?UTF-16BE xx?00?00?00?-?UTF-32LE xx?00?xx?00?-?UTF-16LE xx?xx?xx?xx?-?UTF-8
現在,如果文件以BOM開頭,則如下所示:
00?00?FE?FF?-?UTF-32BE FE?FF?00?xx?-?UTF-16BE FF?FE?00?00?-?UTF-32LE FF?FE?xx?00?-?UTF-16LE EF?BB?BF?xx?-?UTF-8
請注意:
- utf-32be不會以三個空開始,因此不會被識別。
- UTF-32LE第一個字節后面沒有3個空號,因此不會被識別。
- 在前4個字節中,utf-16be只有一個NUL,因此不會被識別。
- 在前4個字節中,utf-16 le只有1個nul,因此不會被識別。
根據實施情況,所有這些可能被錯誤地解釋為UTF-8,然后被誤解或拒絕為無效的UTF-8,或者根本不被承認。
此外,如果像我建議的那樣對有效的JSON進行實現測試,它甚至會拒絕輸入,因為它不會像RFC那樣以ASCII字符<128開頭,因為輸入確實編碼為UTF-8。
其他數據格式
JSON中的BOM是不需要的,是非法的,并且破壞了根據RFC正確工作的軟件。如果當時不使用JSON應該是個不需要考慮的問題,然而,總是有人堅持使用Boms、注釋、不同的引用規則或不同的數據類型來破壞JSON。當然,如果需要的話,任何人都可以自由地使用Boms之類的東西-只是不要叫它JSON。
對于JSON以外的其他數據格式,請查看它的真實外觀。如果唯一的編碼是UTF-*,并且第一個字符必須是小于128的ASCII字符,那么您已經有了確定數據編碼和編碼的所有信息。即使將Boms添加為可選功能,也只會使其更加復雜和容易出錯。
BOM的其他用途
至于JSON或腳本之外的使用,我認為這里已經有了非常好的答案。我想添加更多關于腳本和序列化的詳細信息,因為這是BOM字符導致實際問題的一個例子。
添加回答
舉報