階段一 ascii碼
計算機剛開始只支援英語,其它語言不能夠在計算機上儲存和顯示。ascii碼一共規定了128個字元的編碼,這128個符號(包括32個不能列印出來的控制符號),只占用了乙個位元組的後面7位,最前面的1位統一規定為0。
階段二 ansi編碼(本地編碼)
為使計算機支援更多語言,通常使用0x80~0xff範圍的2個位元組來表示1個字元。比如:漢字「中」在中文作業系統中,使用[0xd6,0xd0]這兩個位元組儲存。不同的國家和地區制定了不同的標準,由此產生了gb2312,big5,jis等各自的編碼標準。這些使用2個位元組來代表乙個字元的各種文字延伸編碼方式,稱為ansi編碼。在簡體中文系統下,ansi編碼代表gb2312編碼,在日文作業系統下,ansi編碼代表jis編碼。不同ansi編碼之間互不相容,當資訊在國際間交流時,無法將屬於兩種語言的文字,儲存在同一段ansi編碼的文字中。
階段三 unicode(國際編碼)
為了使國際間資訊交流更加方便,國際組織制定了unicode字符集,為各種語言中的每乙個字元設定了統一並且唯一的數字編號,以滿足跨語言、跨平台進行文字轉換、處理的要求。unicode當然是乙個很大的集合,現在的規模可以容納100多萬個符號。每個符號的編碼都不一樣,比如,u+0639表示阿拉伯字母ع,u+0041表示英語的大寫字母a,u+4e25表示漢字嚴。需要注意的是,unicode只是乙個符號集,它只規定了符號的二進位制**,卻沒有規定這個二進位制**應該如何儲存。
網際網路的普及,強烈要求出現一種統一的編碼方式。utf-8就是在網際網路上使用最廣的一種unicode的實現方式。其他實現方式還包括utf-16和utf-32,不過在網際網路上基本不用。重複一遍,這裡的關係是,utf-8是unicode的實現方式之一。
utf-8最大的乙個特點,就是它是一種變長的編碼方式。它可以使用1~4個位元組表示乙個符號,根據不同的符號而變化位元組長度。
utf-8的編碼規則很簡單,只有兩條:
1)對於單位元組的符號,位元組的第一位設為0,後面7位為這個符號的unicode碼。因此對於英語字母,utf-8編碼和ascii碼是相同的。
2)對於n位元組的符號(n>1),第乙個位元組的前n位都設為1,第n+1位設為0,後面位元組的前兩位一律設為10。剩下的沒有提及的二進位制位,全部為這個符號的unicode碼。
編碼規則如下表,字母x表示可用編碼的位:
位元組數二進位制表示
有效二進位制位數目
可表示的最大編碼
編碼範圍(16進製制)
10******x
70x7f
0000 0000-0000 007f
2110***xx 10******
110x7ff
0000 0080-0000 07ff
31110***x 10****** 10******
160xffff
0000 0800-0000 ffff
411110*** 10****** 10****** 10******
210x1fffff
0001 0000-0010 ffff
0011 0000-001f ffff之間的編碼暫時不用。
下面,還是以漢字「查」為例,演示如何實現utf-8編碼。
查的unicode是u+67e5(0110 0111 1110 0101),根據上表,可以發現0x67e5處於第三行的範圍內,因此「查」的utf-8編碼需要3個位元組,即格式是「1110***x 10****** 10******」。從「查」的unicode最後乙個二進位制位開始,依次從後向前填入格式中的x,多出的位補0。就得到了「查」的utf-8編碼:11100110 10011111 10100101,轉換為16進製制0xe69fa5。
儲存時可選的編碼方式有:ansi,unicode,unicode big endian和utf-8。
1)ansi是預設的編碼方式。對於英文檔案是ascii編碼,對於簡體中文檔案是gb2312編碼(只針對windows簡體中文版,如果是正體中文版會採用big5碼)。
2)unicode編碼指的是ucs-2編碼方式,即直接用兩個位元組存入字元的unicode碼(對於大於2個位元組的字元無法儲存。utf-16擴充了unicode,包括了一些稀有字元,像我們國家的滿文,藏文等等,兩者基本上等價)。這個選項用的little endian格式。
3)unicode big endian編碼與上乙個選項相對應。
4)utf-8編碼,也就是上面談到的編碼方法。
little endian和big endian
unicode碼可以採用ucs-2格式直接儲存。以漢字「嚴」為例,unicode碼是4e25,需要用兩個位元組儲存,乙個位元組是4e,另乙個位元組是25。儲存的時候,4e在前,25在後,就是big endian方式;25在前,4e在後,就是little endian方式。
unicode規範中定義,每乙個檔案的最前面分別加入乙個表示編碼順序的字元,這個字元的名字叫做「零寬度非換行空格」(zero width no-break space)。如果乙個文字檔案的頭兩個位元組是fe ff,就表示該檔案採用大頭方式;如果頭兩個位元組是ff fe,就表示該檔案採用小頭方式。
在windows中unicode編碼中表示位元組排列順序的這個檔案頭,也叫做bom(byte-order mark),例如:
1)unicode:ff fe 表明是小頭方式儲存。
2)unicode big endian:fe ff 表明是大頭方式儲存。
3)utf-8:ef bb bf 表示這是utf-8編碼。
當乙個軟體開啟乙個文字時,它要做的第一件事是確定這個文字究竟是使用哪種字符集的哪種編碼儲存的。軟體有三種途徑來決定文字的字符集和編碼:
最標準的途徑是檢測文字最開頭的幾個位元組,如下表:
開頭位元組
charset/encoding
ef bb bf
utf-8
ff fe
utf-16/ucs-2, little endian
fe ff
utf-16/ucs-2, big endian
ff fe 00 00
utf-32/ucs-4, little endian
00 00 fe ff
utf-32/ucs-4, big-endian
但是某些文字沒有這些位於開頭的字符集標記,比如centos下的gedit儲存文字時就不會新增這些標記。因此,軟體不能依賴於這種途徑。這時,軟體可以採取一種比較安全的方式來決定字符集及其編碼,那就是彈出乙個對話方塊來請示使用者,例如用microsoft word開啟這種文字,word就會彈出乙個對話方塊讓你選擇編碼。
如果軟體不想麻煩使用者,或者它不方便向使用者請示,那它只能採取自己「猜」的方法,軟體可以根據整個文字的特徵來猜測它可能屬於哪個charset,這就很可能不准了。windows下的記事本和linux下的文字編輯器都是這樣做的,但是用它們開啟或另存為的時候可以選擇編碼方式。
字元編碼總結
記事本編碼格式**
字元編碼問題
字元編碼主要分兩種 mbcs以及 unicode。以 c cc 為例,以 char 為單位的陣列使用mbcs編碼 如 ascii,gb2312,big5 以wchar t 為單位的陣列使用unicode作為編碼。比如你的程式中使用 char sztitle 窗體標題 此時,sztitle字串使用的的...
字元編碼問題
utf 8 1.單位元組的字元,位元組的第一位設為0,對於英語文字,utf 8碼只占用乙個位元組,和ascii碼完全相同 2.n個位元組的字元 n 1 第乙個位元組的前n位設為1,第n 1位設為0,後面位元組的前兩位都設為10,這n個位元組的其餘空位填充該字元unicode碼,高位用0補足。除了格式...
字元編碼問題
關鍵字 編碼集 bstr lpstr lpcstr lpwstr lpcwstr lptstr lpctstr cstring 1 編碼集 1 ascii編碼集 單位元組00h 7fh範圍 最高位為0 2 擴充套件ascii編碼 單位元組80h ffh範圍 最高位為1 3 gb2312 採用兩個位元...