Unicode 筆記

saucej發表於2014-12-02

位元組和字元的區別

  位元組(octet)是一個八位的儲存單元,0-255 , 標準的assic,
  字元(character或者word)為語言意義上的符號,範圍就不一定了。UCS-2中定義的字元範圍為0~65535,它的一個字元佔用兩個位元組。

big-endian和Littl Endian

一個字元可能佔用多個位元組,多個位元組的儲存方式在x86架構下采用little-endian(小端,低位編址),最為符合人的思維的表示方式(地址低位儲存值的低位),當在windows記憶體除錯時候根據dword , 還是word讀取值。
  另外一種方式為big-endian(大端,高位編址) 網路程式設計中常用,常應用與網路位元組序。(最為直觀的表示)列印時候直接根據
  地制值從低位列印到高位輸出)
 例子2:如果我們將0x1234abcd寫入到以0x0000開始的記憶體中,則結果為
       big-endian   little-endian
   0x0000    0x12         0xcd
   0x0001    0x23         0xab
   0x0002    0xab         0x34
   0x0003    0xcd         0x12

UCS-2和UCS-4

Unicode是為整合全世界的所有語言文字而誕生的。任何文字在Unicode中都對應一個值,這個值稱為程式碼點(code point)。程式碼點的值通常寫成 U+ABCD 的格式。而文字和程式碼點之間的對應關係就是UCS-2(Universal Character Set coded in 2 octets)。顧名思義,UCS-2是用兩個位元組來表示程式碼點,其取值範圍為 U+0000~U+FFFF。
UCS-4,即用四個位元組表示程式碼點。它的範圍為 U+00000000~U+7FFFFFFF,其中 U+00000000~U+0000FFFF和UCS-2是一樣的。從而可以表示更多的文字。
UCS-2和UCS-4只規定了程式碼點和文字之間的對應關係,並沒有規定程式碼點在計算機中如何儲存(前面提到的little-endian還是big endian,通過在檔案頭前加入BOM,FE FF代表big endian)。規定儲存方式的稱為UTF(Unicode Transformation Format),其中應用較多的就是UTF-16和UTF-8了。

UTF-16和UTF-32

UTF-16是完全對應於UCS-2的,即把UCS-2規定的程式碼點通過Big Endian或Little Endian方式直接儲存下來。UTF-16包括三種:UTF-16(預設為big endian),UTF-16BE(Big Endian),UTF-16LE(Little Endian)
UTF-16BE和UTF-16LE不難理解,而UTF-16就需要通過在檔案開頭以名為BOM(Byte Order Mark)的字元來表明檔案是Big Endian還是Little Endian。BOM為U+FEFF這個字元。
舉個例子。“ABC”這三個字元用各種方式編碼後的結果如下:

 

UTF-16BE 00 41 00 42 00 43
UTF-16LE 41 00 42 00 43 00
UTF-16(Big Endian) FE FF 00 41 00 42 00 43
UTF-16(Little Endian) FF FE 41 00 42 00 43 00
UTF-16(不帶BOM) 00 41 00 42 00 43

 

Windows平臺下預設的Unicode編碼為Little Endian的UTF-16(即上述的 FF FE 41 00 42 00 43 00)你可以開啟記事本,寫上ABC,然後儲存,再用二進位制編輯器看看它的編碼結果。
另外,UTF-16還能表示一部分的UCS-4程式碼點——U+10000~U+10FFFF。表示演算法比較複雜,

UTF-32

UTF-32用四個位元組表示程式碼點,這樣就可以完全表示UCS-4的所有程式碼點,而無需像UTF-16那樣使用複雜的演算法。與UTF-16類似,UTF-32也包括UTF-32、UTF-32BE、UTF-32LE三種編碼,UTF-32也同樣需要BOM字元。僅用'ABC'舉例:

UTF-32BE 00 00 00 41 00 00 00 42 00 00 00 43
UTF-32LE 41 00 00 00 42 00 00 00 43 00 00 00
UTF-32(Big Endian) 00 00 FE FF 00 00 00 41 00 00 00 42 00 00 00 43
UTF-32(Little Endian) FF FE 00 00 41 00 00 00 42 00 00 00 43 00 00 00
UTF-32(不帶BOM) 00 00 00 41 00 00 00 42 00 00 00 43

UTF-8

UTF-16和UTF-32的一個缺點就是它們固定使用兩個或四個位元組,這樣在表示純ASCII檔案時會有很多00位元組,造成浪費。而RFC3629定義的UTF-8則解決了這個問題。

UTF-8用1~4個位元組來表示程式碼點。UTF-8 預設也是big endian表示方式如下:

UCS-2 (UCS-4) 位序列 第一位元組 第二位元組 第三位元組 第四位元組
U+0000 .. U+007F 00000000-0xxxxxxx 0xxxxxxx      
U+0080 .. U+07FF 00000xxx-xxyyyyyy 110xxxxx 10yyyyyy    
U+0800 .. U+FFFF xxxxyyyy-yyzzzzzz 1110xxxx 10yyyyyy 10zzzzzz  
U+10000..U+1FFFFF 00000000-000wwwxx-
xxxxyyyy-yyzzzzzzz
11110www 10xxxxxx 10yyyyyy 10zzzzzz

可見,ASCII字元(U+0000~U+007F)部分完全使用一個位元組,避免了儲存空間的浪費。而且UTF-8不再需要BOM位元組。

標準ascii 只有127個字元 7f  = 2^3*2^4 = 127. 第一位置0,表示只佔用一個字元。

另外,從上表中可以看出,單位元組編碼的第一位元組為[00-7F],雙位元組編碼的第一位元組為[C2-DF],三位元組編碼的第一位元組為[E0-EF]。這樣只要看到第一個位元組的範圍就可以知道編碼的位元組數。這樣也可以大大簡化演算法。

gb2312

1981年5月1日開始實施的一套國家標準,標準號是GB 2312—1980。 基本集共收入漢字6763個和非漢字圖形字元682個。整個字符集分成94個區,每區有94個位。每個區位上只有一個字元,因此可用所在的區和位來對漢字進行編碼,稱為區位碼

1995年又頒佈了《漢字編碼擴充套件規範》(GBK)。GBK與GB 2312—1980國家標準所對應的內碼標準相容

GB 2312中對所收漢字進行了“分割槽”處理,每區含有94個漢字/符號。這種表示方式也稱為區位碼
01-09區為特殊符號。
16-55區為一級漢字,按拼音排序。
56-87區為二級漢字,按部首/筆畫排序。
10-15區及88-94區則未有編碼
舉例來說,“啊”字是GB2312之中的第一個漢字,它的區位碼就是1601。

 

 

相關文章