ANSI UNICODE UTF 位元組序 BOM

2021-05-11 16:20:58 字數 3040 閱讀 2469

utf的位元組序和bom

utf-8以位元組為編碼單元,沒有位元組序的問題。utf-16以兩個位元組為編碼單元,在解釋乙個utf-16文字前,首先要弄清楚每個編碼單元的位元組序。例如收到乙個「奎」的unicode編碼是594e,「乙」的unicode編碼是4e59。如果我們收到utf-16位元組流「594e」,那麼這是「奎」還是「乙」?

unicode規範中推薦的標記位元組順序的方法是bom。bom不是「bill of material」的bom表,而是byte order mark。bom是乙個有點小聰明的想法:在ucs編碼中有乙個叫做」zero width no-break space」的字元,它的編碼是feff。而fffe在ucs中是不存在的字元,所以不應該出現在實際傳輸中。ucs規範建議我們在傳輸位元組流前,先傳輸字元」zero width no-break space」。

這樣如果接收者收到feff,就表明這個位元組流是big-endian的;如果收到fffe,就表明這個位元組流是little-endian的。因此字元」zero width no-break space」又被稱作bom。

utf-8不需要bom來表明位元組順序,但可以用bom來表明編碼方式。字元」zero width no-break space」的utf-8編碼是ef bb bf。所以如果接收者收到以ef bb bf開頭的位元組流,就知道這是utf-8編碼了。

windows就是使用bom來標記文字檔案的編碼方式的。

好了﹐這些問題解決後﹐我們就來做單純的文字檔案的編碼識別﹐讀取與寫入測試吧。

以windows的notepad為例(其它的文字檔案讀取軟體的原理應該也差不多﹐只是會多一些特殊的判斷演算法而已)。

notepad預設有四種編碼來儲存和讀取文字檔案。分別是﹕

ansi,unicode,unicode-big-endian和utf-8。

首先來講ansi吧﹐這個是windows作業系統在區域與語言塊設定的編碼(也就是系統預設的編碼)﹐因此像繁體作業系統就是big5,而簡體作業系統則是gbk。

而unicode和utf-8這兩種格式相信大家已經有所了解(當然前者是unicode-16)

而unicode-big-endian是什麼意思呢﹐它與unicode幾乎一樣﹐只是它把高位放在前面(而後者則剛好相反)

上面的摘錄已經有所說明﹐這裡再解釋一下﹕

如同樣是字元」a」﹐在以下幾種格式中的儲存形式分別是﹕

utf-16 big-endian : 00 41

utf-16 little-endian : 41 00

utf-32 big-endian : 00 00 00 41

utf-32 little-endian : 41 00 00 00

根據bom的規則﹐因此在一段位元組流開始時﹐如果接收到以下位元組﹐則分別表明了該文字檔案的編碼。

utf-8: ef bb bf

utf-16 : ff fe

utf-16 big-endian: fe ff

utf-32 little-endian: ff fe 00 00

utf-32 big-endian: 00 00 fe ff

而如果不是以這個開頭﹐那程式則會以ansi,也就是系統預設編碼讀取。

所以現在我們來做個測試就可以很清楚地對以上的東東進行驗證了。

1.用notepad輸入」漢a」這2個字元﹐然後分別儲存成ansi,unicode,unicode-big-endian和utf-8,名字分別取為ansi.txt,unicode.txt,unicode_b.txt,utf8.txt,並且放在c盤根目錄下

2.用以下程式進行驗證

using system;

using system.collections;

using system.io;

public class myclass

catch(exception ex)

finally

}public static void main()

public static void sixttwo(string sixstr)

);foreach(string s in tmp)

wl(」");

}private static void wl(string text, params object args)

private static void rl()

private static void break()

}3.以下是輸出格式﹕

ansi檔案格式的位元組流﹕

ba-ba-41

10111010 10111010 01000001

unicode檔案格式的位元組流﹕

ff-fe-49-6c-41-00

11111111 11111110 01001001 01101100 01000001 00000000

unicode-big-endian檔案格式的位元組流﹕

fe-ff-6c-49-00-41

11111110 11111111 01101100 01001001 00000000 01000001

utf-8檔案格式的位元組流﹕

ef-bb-bf-e6-b1-89-41

11101111 10111011 10111111 11100110 10110001 10001001 01000001

從以上結果可以很容易的看到baba正是」漢」字的gb2312編碼﹐當然我的作業系統是繁體的﹐如果我直接雙擊開啟﹐則可以看到」犖a」﹐這是亂碼﹐因為我的系統baba查的是big5﹐而baba的big5碼正是」犖」

然而還有其它很多程式﹐像ie呀,它可以使用meta標籤來識別檔案的編碼,xml也是可以通過encoding屬性來說明檔案的編碼的﹐所以這些程式的識別方法和普通的又有些不同罷了。

同樣﹐寫乙個文字檔案時﹐先寫入這些標記符﹐則也會幫助notepad識別這些檔案的編碼(當然.net專門提供了一些類別﹐如streamwriter﹐可以直接存成某種編碼的格式)。

至於各種encoding之間的轉換﹐我想也不必多說了﹐通過encoding類的convert,getbytes和getstring方法是很容易進行轉換的。

ANSI, UNICODE,UTF8編碼的區別

本地化過程中涉及到原始檔和目標檔案的傳輸問題,這時候編碼就顯得很重要。中文的網頁和作業系統中通常採用ansi編碼,這也是微軟os的乙個字元標準。對於ansi,不同的國家和地區制定了不同的標準,由此產生了gb2312 簡體中文 big5 正體中文 jis 日文 等各自的編碼標準。但不同的ansi編碼在...

ANSI, UNICODE,UTF8編碼的區別

本地化過程中涉及到原始檔和目標檔案的傳輸問題,這時候編碼就顯得很重要。中文的網頁和作業系統中通常採用ansi編碼,這也是微軟os的乙個字元標準。對於ansi,不同的國家和地區制定了不同的標準,由此產生了gb2312 簡體中文 big5 正體中文 jis 日文 等各自的編碼標準。但不同的ansi編碼在...

Python檢測重複字 部分中華字經重複字檢測

中文去標點符號,中文繁體字轉化簡體字,列表檢測並輸出重複項,list當多個相同值時索引 關於去標點,使用包 zhon,直接pip即可 安裝及使用 關於中文繁簡轉換,安裝opencc python 安裝及使用 coding utf 8 author zhr date 2019 10 25 20 26 ...