BOM BOM BOM

為了徹底了解BOM,認真的去查了一下資料,可惜,國內的相關資料不太多,而且都說得不清不楚,讓人看了就想皺眉,所以,乾脆來自己整理一下資料,免得以後要用又找不到。

簡單一點來講,U+FFFE對於Unicode標準有兩項作用:

1. 又稱之為ZERO WIDTH NO-BREAK SPACE,顧名思義,它是個沒有寬度也沒有斷字的空白,簡單來講,就是個讓你感覺不到它的存在的空白啦!在那之後,也有U+00a0 (NO-BREAK SPACE)以及U+200b (ZERO WIDTH SPACE)兩種空白。有時候,我們會需要連結兩個完全不同的字,而且不希望他們之間有空白或是斷字,不過到底是哪裡會用到,我也完全不知道。

2. 就是大家熟知的BOM,Byte Order Mark。什麼是 Byte-Order?根據 mfhsieh在他的部落當中的說明:

在一些平台上,是把代表數值較大的 byte 放在前面,這稱為 Big Endian (BE) 的系統;有些平台則相反,是把代表數值較小的 byte 放在前面,稱為 Little Endian (LE) 的系統。像 Zaurus 是屬於 BE 的系統,而 wintel 架構則屬 LE。若同以 “中” 這個字來看,它的 Unicode 是 U+4E2D,故在 BE 上是以 0x4E 0x2D 來表示,而在 LE 上則以 0x2D 0x4E 來表示。

而在某些平台,尤其是Win32的系統,txt檔案都喜歡在檔案的最開頭以 U+FEFF 這個字元來辦識該檔案是使用 BE 或 LE 的方式來編碼,不過它到底是怎麼去判斷是哪種編碼型態?打開Notepad,從存檔的對話視窗當中你可以看到他有幾種不同的存檔編碼格式可以選擇:

  • ANSI
  • Unicode
  • Unicode big endian
  • Utf-8

如果說是LE(預設的Unicode),BOM為0xFF 0xFE,不過因為LE的Unicode定義當中不存在U+FFFE的字元,因此如果開頭兩個byte是 0xFF 0xFE,就是LE的檔案類型;如果是BE,BOM就是 0xFE 0xFF,不過這兩個字元在Unicode當中是不佔空間的 space 空白,所以看起來還是沒有東西。也就是說,雖然你看不到這些字元,但它卻悄悄的指出了檔案的編碼資訊。當一個應用程式在純文字檔案的開頭找到了U+FFFE這個字元,就代表這個檔案是Unicode的檔案,它會長成下面這樣:

  • 00 00 fe ff UTF-32, Big Endian
  • fe ff 00 00 UTF-32, Little Endian
  • fe ff ## ## UTF-16, Big Endian
  • ff fe ## ## UTF-16, Little Endian
  • ef bb bf UTF-8

Microsoft與BOM

許多Windows 軟體(包括Windows 筆記本) 在UTF-8編碼的檔案的開頭加入一段位元組EF BB BF,這是編碼成UTF-8的Byte Order Mark U+FEFF,而無法處理UTF-8的文字編輯器和瀏覽器則會顯示為ISO-8859-1字符””。

在進入到NT系統的時候,你可以在Notepad當中選擇存成Unicode格式,其實當時的格式正確來講是Little Endian UTF-16,是當時普遍支援的格式,不過當時的MS給了他一個含糊曖昧的名稱,叫做Unicode。然後到了Windows 2000的時候,MS又幫Notepad加上可以存成Big Endian UTF-16格式的選項,不過因為之前已經把Little Endian UTF-16這個格式叫做Unicode了,所以只好把這個新的格式叫做Unicode Big Endian。好吧,這名稱也不至於太差,總比叫UnicodeFFFE還要來得好聽吧!XD 不過不管是Unicode Big Endian還是UnicodeFFFE都造成了某些人的困擾,內心的OS在吶喊:阿都是Unicode,哪裡不一樣啦!

這些人內心的OS其實一點也沒錯,不過說真的,麻木沒有感覺的人還是佔了大多數,所以,當時也就不了了之。不過這種情況到現在可以說是出現了一些糟糕的麻煩,因為Notepad也加上另存成UTF-8的選項,理所當然,BOM的問題就浮了出來。

當文件當中出現了ASCII的字元時,理論上來講,應該要存成UTF-8的編碼格式,否則就是根據軟體本身預設的編碼格式。當這個檔案為UTF-8的時候,為了避免下一次開檔案時,軟體認不得文件的編碼,所以它們就加入BOM的字元來辨識該文件是否為Unicode的檔案。這偷偷加入的玩意兒,如果只是在平常時候編輯一般的單純文件,是無傷大雅的,使用者也不會有任何的感覺,不過萬一使用者是用他來編輯一些XML(聽說現在XML已經支援了)或是HTML的檔案,因為他們不接受BOM,就會產生錯誤,因為人們仍然在使用這種便利的工具來編輯自己的檔案….

Raymond Chen寫了一篇文章 Some files come up strange in Notepad,裡面有提到關於Notepad的問題,不過一般人仍然沒有對Notepad這種行徑有任何抱怨。

後來當然是越來越多人發現這個機車的問題,就開始抱怨起Microsoft的Notepad是如何機車的引起這些問題,然後也開始有人抱怨要不是當初Notepad幹這種蠢事出來,W3C與Unicode也不會支援UTF-8 BOM這種鬼東西;順便一提的是,其實不只是Notepad是這樣,Frontpage 2000也是這德性,不過Frontpage 2002與2003已經修正了這個問題。

然而根據一位長年維護Windows Notepad軟體的工程師所解釋的,因為Notepad只能編輯Unicode檔案,所以不管是什麼編碼,都必須先轉換成Unicode編碼才能夠被Notepad所編輯,其實Notepad當然也可以不要加上BOM,不過如果不加的話,就必須仰賴靠不住的IsTextUnicode() API 來「猜測」使用者到底是使用何種編碼。

不管怎麼說,BOM這個東西大概是只要你用Notepade開檔案編輯都會出現的困擾,雖然有人說這是微軟貼心(?)的設計,因為他們總是為消費者著想(ㄝ?你是說定價嗎?),不過我怎麼看,都只覺得是眼光不夠遠大所產生出來的擦屁股行為;或許現在在這邊抱怨微軟的BOM也於事無補,因為太多人用Notepad寫程式,所以只能費點功夫搞清楚到底BOM的問題癥結在哪裡,不過搞清楚了以後,好像還是找不出什麼有效的解決辦法,除了不要用奇怪的編輯器外。

延伸閱讀:

One thought on “BOM BOM BOM

Leave a comment