位元組順序記號 - 维基百科
文章推薦指數: 80 %
位元組順序記號(英語:byte-order mark,BOM)是位於碼點 U+FEFF 的統一碼字符的名称。
當以UTF-16或UTF-32來將UCS/統一碼字符所組成的字串編碼時,這個字符被用來標示 ...
位元組順序記號
語言
監視
編輯
位元組順序記號(英語:byte-ordermark,BOM)是位於碼點U+FEFF的統一碼字元的名稱。
當以UTF-16或UTF-32來將UCS/統一碼字元所組成的字串編碼時,這個字元被用來標示其位元組序。
它常被用來當做標示檔案是以UTF-8、UTF-16或UTF-32編碼的記號。
位元組順序記號通常有幾種涵義[1]:
在16位元和32位元的情況下,文字流的位元組順序。
表示文字流非常有可能是Unicode編碼。
使用的是哪一種Unicode字元編碼。
位元組順序記號的使用是選擇性的。
它的存在會干擾那些不希望檔案開頭出現非ASCII字元、但可以用其他方式處理文字流的軟體對於UTF-8的使用。
Unicode可以以8位元、16位元或32位元整數為單位進行編碼。
對於16位元和32位元的表示方法,從任意來源接收文字的電腦需要知道整數是以何種位元組順序編碼的。
位元組順序記號的編碼方式與文件檔案的其他部分相同,如果它的位元組被調換,就會變成一個非字元的Unicode碼位。
因此,存取文字的過程中,可以透過檢查這頭幾個位元組來確定位元組順序,而不需要文字流本身以外的一些約定或元資料。
一般來說,如果有必要,接收資料的電腦會將位元組換成自己的位元組順序,不再需要位元組順序記號進行處理。
每個Unicode編碼(包括Unicode標準以外的編碼,如UTF-7,見下表)的BOM位元組序列都不一樣,而且這些序列都不可能出現在以其他編碼儲存的文字流的開頭。
因此,在文字流的開頭放置一個編碼的BOM,可以表明文字是Unicode,並識別所使用的編碼方案。
這種對BOM字元的使用被稱為「Unicode簽名」[2]。
目次
1使用
1.1UTF-8
1.2UTF-16
1.3UTF-32
2不同編碼的位元組順序記號的表示
3另見
4參考文獻
5外部連結
使用編輯
字元U+FEFF如果出現在位元組流的開頭,則用來標識該位元組流的位元組序,是高位在前還是低位在前。
如果它出現在位元組流的中間,則表達零寬度非換行空格的意義,使用者看起來就是一個空格。
從Unicode3.2開始,U+FEFF只能出現在位元組流的開頭,只能用於標識位元組序,就如它的名稱——位元組順序記號——所表示的一樣;除此以外的用法已被捨棄。
取而代之的是,使用U+2060來表達零寬度無斷空白。
UTF-8編輯
在UTF-8中,雖然在Unicode標準上允許位元組順序記號的存在[3],但實際上並不一定需要[4]。
UTF-8編碼過的位元組順序記號則被用來標示它是UTF-8的檔案。
它只用來標示一個UTF-8的檔案,而不用來說明位元組順序[5]。
但同時,該標準也不建議在有位元組順序記號的情況下將其刪除,以便在不同的編碼之間轉換時不會丟失資訊,並讓依賴位元組順序記號的程式能順利運作[6][7]。
IETF建議,如果一個協定(a)總是使用UTF-8,或者(b)有一些其他方法來表明正在使用的編碼,那麼它「應該禁止使用U+FEFF作為簽名」[8]。
許多視窗程式(包含記事本)會需要添加位元組順序記號到UTF-8檔案,否則將無法正確解析編碼,而出現亂碼。
然而,在類Unix系統(大量使用文字檔案,用於檔案格式,用於行程間通訊)中,這種做法則不被建議採用。
因為它會妨礙到如解譯器指令碼開頭的Shebang等的一些重要的碼的正確處理。
它亦會影響到無法識別它的程式語言。
如gcc會報告原始碼檔開頭有無法識別的字元。
而在PHP中,如果沒有啟用輸出緩衝(outputbuffering),它會使得頁面內容開始被送往瀏覽器(即:使用者標頭檔已被送出),這使PHP指令碼無法指定使用者標頭檔(HTTPHeader)。
位元組順序記號在UTF-8中被表示為序列0xEF0xBB0xBF,對大部分未準備好處理UTF-8的文字編輯器及網頁瀏覽器而言,在ISO-8859-1的環境中則會顯示。
Unicode標準允許在UTF-8中使用BOM,但並不要求或推薦使用它。
位元組順序在UTF-8中沒有任何意義,所以它在UTF-8中的唯一用途是在開始時發出訊號,表明文字流是用UTF-8編碼的,或者表明它是從包含可選BOM的文字流轉換到UTF-8的。
該標準也不建議在有BOM的情況下將其刪除,以便在不同的編碼之間往返不會丟失資訊,並使依賴BOM的代碼繼續工作。
IETF建議,如果一個協定要麼(a)總是使用UTF-8,要麼(b)有一些其他方法來表明正在使用的編碼,那麼它"應該禁止使用U+FEFF作為簽名"。
UTF-8是一種稀疏的編碼,意思是很大一部分可能的字元組合不會產生有效的UTF-8文字。
任何其他編碼的二進制資料和文字都可能包含UTF-8無效的字元序列,唯一的例外是當文字純粹由ASCII範圍的字元組成的時候。
因為所有的現代編碼都使用ASCII範圍的位元組來表示ASCII字元,所以無論發出這些位元組的系統打算使用什麼編碼,純ASCII的文字都可以被安全地解釋為UTF-8。
由於這些考慮,使用啟發式的分析方法可以很有把握地檢測出檔案是否使用UTF-8,而不需要加入BOM。
另一方面,微軟的編譯器[9]和解釋器,以及許多MicrosoftWindows上的軟體,如記事本,都將BOM視為一個必要的神奇數字,而不是使用啟發式分析法。
這些工具在將文字儲存為UTF-8時添加了BOM,並且只有在BOM存在或是檔案只包含ASCII字元時才能解釋UTF-8。
WindowsPowerShell(截至5.1版本)在儲存UTF-8的XML檔案檔時,會添加一個BOM。
然而,PowerShellCore6在一些cmdlets上增加了一個-Encoding開關,稱為「utf8NoBOM」,這樣就可以在沒有BOM的情況下儲存檔案檔。
Google文件在將檔案檔轉換為純文字檔案以供下載時也會添加BOM。
UTF-16編輯
在UTF-16中,位元組順序記號被放置為檔案或文字串流的第一個字元,以標示在此檔案或文字串流中,以所有十六位元為單位的字碼的端序(位元組順序)。
如果試圖用錯誤的位元組順序來讀取這個流,位元組將被調換,從而產生字元U+FFFE,這個字元被Unicode定義為「非字元」,不應該出現在文字中。
例如,值為U+FFFE的碼位被保證將不會被指定成一個統一碼字元。
這意味著0xFF、0xFE將只能被解釋成小端序中的U+FEFF(因為不可能是大端序中的U+FFFE)。
如果十六位元單位被表示成大端序,這位元組順序記號字元在序列中將呈現0xFE,其後跟著0xFF(其中的0x用來標示十六進位)。
如果十六位元單位使用小端序,這個位元組序列為0xFF,其後接著0xFE。
這兩個序列都不是有效的UTF-8,所以它們的出現表明該檔案不是用UTF-8編碼的。
對於網際網路號碼分配局註冊的字元集UTF-16BE和UTF-16LE,不應該使用位元組順序記號標記,因為這些字元集的名稱已經決定了位元組順序。
如果在這樣的文字串流中的任何地方遇到U+FEFF,將被解釋為一個「零寬度無斷點空間」。
如果沒有位元組順序記號,可以透過搜尋ASCII字元(即與0x20-0x7E範圍內的位元組相鄰的0位元組,還有CR和LF的0x0A和0x0D)來猜測該文字是否為UTF-16及其位元組順序。
大量的(即遠遠高於隨機)相同的順序是UTF-16的一個非常好的指示,而0是在偶數還是奇數位元組中表明了位元組的順序。
然而,這依然可能會導致假陽性和假陰性。
Unicode標準的一致性條款D98(第3.10節)規定:「UTF-16編碼方案可以以BOM開始,也可以不以BOM開始。
然而,當沒有BOM時,在沒有高層協定的情況下,UTF-16編碼方案的位元組順序是大端序。
」是否有更高層次的協定是可以解釋的。
例如,在一台本地位元組順序為小端序的電腦上的檔案,可能被默認為是以UTF-16LE編碼。
因此,大端序的推定被廣泛地忽略了。
在HTML5中使用的W3C/WHATWG編碼標準規定,標記為「utf-16」或「utf-16le」的內容將被解釋為小端序,「以處理部署的內容」[10]。
然而,如果出現了位元組順序記號,那麼該記號將被視為「比其他任何東西都更有權威性」[11]。
將UTF-16解釋為基於位元組的編碼的程式可能會顯示出亂七八糟的字元,但是ASCII字元會被識別出來,因為UTF-16表示的低字元與ASCII代碼相同,因此會顯示相同的字元。
0的上字元可以顯示為無、空白、句號,或其他一些不變的字形。
UTF-32編輯
雖然位元組順序記號亦可以用於UTF-32,但這個編碼很少用於傳輸,其規則如同UTF-16。
小端序UTF-32的BOM等同小端序UTF-16的BOM圖案後面加上一個NUL字元,這是一個不尋常的例子,即BOM在兩種不同的編碼中是相同的形式。
使用BOM來識別編碼的程式員必須分辨檔案是UTF-32編碼還是單純以NUL作為第一個字元。
不同編碼的位元組順序記號的表示編輯
編碼
表示(十六進位)
表示(十進位)
UTF-8
EFBBBF
239187191
UTF-16(大端序)
FEFF
254255
UTF-16(小端序)
FFFE
255254
UTF-32(大端序)
0000FEFF
00254255
UTF-32(小端序)
FFFE0000
25525400
UTF-7
2B2F76和以下的一個位元組:[38|39|2B|2F]
4347118和以下的一個位元組:[56|57|43|47]
UTF-1
F7644C
24710076
UTF-EBCDIC(英語:UTF-EBCDIC)
DD736673
221115102115
Unicode標準壓縮方案(英語:StandardCompressionSchemeforUnicode)
0EFEFF
14254255
BOCU-1(英語:Binary_Ordered_Compression_for_Unicode)
FBEE28及可能跟隨著FF
25123840及可能跟隨著255
GB-18030
84319533
1324914951
另見編輯
左至右符號
右至左符號參考文獻編輯
^FAQ-UTF-8,UTF-16,UTF-32&BOM.Unicode.org.[2017-01-28].(原始內容存檔於2021-05-02).
^TheUnicode®StandardVersion9.0(PDF).TheUnicodeConsortium.[2021-06-16].(原始內容存檔(PDF)於2021-05-07).
^TheUnicodeStandard5.0,Chapter2:GeneralStructure(PDF):36.[2009-03-29].(原始內容存檔(PDF)於2021-04-22).Table2-4.TheSevenUnicodeEncodingSchemes
^TheUnicodeStandard5.0,Chapter2:GeneralStructure(PDF):36.[2008-11-30].(原始內容存檔(PDF)於2021-04-22).UseofaBOMisneitherrequirednorrecommendedforUTF-8,butmaybeencounteredincontextswhereUTF-8dataisconvertedfromotherencodingformsthatuseaBOMorwheretheBOMisusedasaUTF-8signature
^FAQ-UTF-8,UTF-16,UTF-32&BOM:CanaUTF-8datastreamcontaintheBOMcharacter(inUTF-8form)?Ifyes,thencanIstillassumetheremainingUTF-8bytesareinbig-endianorder?.[2008-03-29].(原始內容存檔於2012-09-01).
^Re:pre-HTML5andtheBOMfromAsmusFreytagon2012-07-13(UnicodeMailListArchive).Unicode.org.[2012-07-14].(原始內容存檔於2019-06-16).
^BugID:JDK-6378911UTF-8decoderhandlingofbyte-ordermarkhaschanged.Bugs.sun.com.[2017-01-28].(原始內容存檔於2017-12-19).
^Yergeau,Francois.UTF-8,atransformationformatofISO10646.IETF.November2003[May15,2014].RFC3629.
^AlfP.Steinbach.Unicodepart1:Windowsconsolei/oapproaches.2011[24March2012].(原始內容存檔於2012-03-22).However,sincetheC++sourcecodewasencodedasUTF-8withoutBOM(asisusualinLinux),theVisualC++compilererroneouslyassumedthatthesourcecodewasencodedasWindowsANSI.
^UTF-16LE.EncodingStandard.WHATWG.[2021-06-17].(原始內容存檔於2015-02-04).
^Decode.EncodingStandard.WHATWG.[2021-06-17].(原始內容存檔於2015-02-04).
外部連結編輯
UnicodeFAQ:UTF-8,UTF-16,UTF-32&BOM(頁面存檔備份,存於網際網路檔案館)
TheUnicodeStandard,chapter2.6EncodingSchemes(頁面存檔備份,存於網際網路檔案館)
TheUnicodeStandard,chapter2.13SpecialCharactersandNoncharacters,sectionByteOrderMark(BOM)(頁面存檔備份,存於網際網路檔案館)
TheUnicodeStandard,chapter16.8Specials,sectionByteOrderMark(BOM):U+FEFF(頁面存檔備份,存於網際網路檔案館)
取自「https://zh.wikipedia.org/w/index.php?title=位元組順序記號&oldid=73215405」
延伸文章資訊
- 1java讀取文字檔案異常 - 程式人生
百度搜了一下這個uFEFF 原因如下在Windows下用文字編輯器建立的文字檔案,如果選擇以UTF-8等Unicode格式儲存,會在檔案頭(第一個字元)加入一個BOM ...
- 2Why UTF-8 BOM bytes efbbbf can be replaced by \ufeff?
The byte order mark (BOM) is a Unicode character, U+FEFF BYTE ORDER MARK (BOM), whose appearance ...
- 3python去除BOM头\ufeff等特殊字符- 凌度- 博客园
1.\ufeff 字节顺序标记去掉\ufeff,只需改一下编码就行,把UTF-8编码改成UTF-8-sigwith open(file_path, mode='r', encodin.
- 4Python: 讀取文件開頭出現\ufeff - 羔羊的實驗紀錄簿
今天讀取影像感測器存出來的參數時,發現讀進來的檔案多了 \ufeff 這個 ... 當文件儲存 utf-8 編碼時,有包含BOM (檔首),此時直接用 utf-8 格式去讀 ...
- 5IDE非法字符'\ufeff'报错| UTF8与UTF8-BOM,大端与小端等 ...
BOM. 出于好奇,我们查一下这个编码 \\ufeff 是个什么东东,查询得知,这是一个标识字节存储顺序的编码。 这个涉及到一个名词:BOM。