4 回答

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

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

TA貢獻(xiàn)1998條經(jīng)驗(yàn) 獲得超6個(gè)贊
不包含文本的文件不再是空的,因?yàn)樗鼈兛偸前珺OM。 在UTF-8的ASCII子集中保存文本的文件不再是ASCII,因?yàn)锽OM不是ASCII,這使得一些現(xiàn)有工具崩潰,用戶可能無法替換這些遺留工具。 不可能將多個(gè)文件連接在一起,因?yàn)楝F(xiàn)在每個(gè)文件在開始時(shí)都有一個(gè)BOM。
這是不夠的,因?yàn)槿我庾止?jié)序列可能會(huì)以構(gòu)成BOM的確切序列開始。 沒有必要,因?yàn)槟梢韵褡x取UTF-8一樣讀取字節(jié);如果成功,則定義為有效的UTF-8。

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