中文編碼問題

1.為什麼要中文編碼?

答:為了把漢字存儲在計算機中。

前車之鑒:為了把中文存儲在計算機中,我們先看看英文是如何存儲在計算機中。

ASCII碼(American Standard Code for Information Interchange,美國信息交換標準代碼),

ASCII 碼使用指定的7 位或8 位二進位數組合來表示128 或256 種可能的字元。

7位ASCII碼錶

  • 包括33個控制碼,一個空格碼,和94個形象碼
  • 形象碼中包括了英文大小寫字母,阿拉伯數字,標點符號等

2.引入:英文字母有26個,中文漢字有多少個呢?怎麼編碼呢?

第一個問題:國家定義了標準:

GB 2312是中國國家標準簡體中文字符集,全稱《信息交換用漢字編碼字符集·基本集》,又稱GB0。

該標準收漢字6763個,第一級3755個,位於16至55區,55區的最後5個字元沒有定義;第二級3008個,位於56至87區

  GB 2312的出現,基本滿足了漢字的計算機處理需要,它所收錄的漢字已經覆蓋中國大陸99.75%的使用頻率。

區位碼錶:查表時先查區號,再查行、列,例如:「啊」是1601。

第二個問題:如何編碼:

1.兼容問題:在使用GB2312的程序通常採用EUC儲存方法,以便兼容於ASCII,每個漢字及符號以兩個位元組來表示。第一個位元組稱為「高位位元組」,第二個位元組稱為「低位位元組」。

如何兼容:

1.ASCII碼擴展:

1.七位擴展到八位,增加128個碼元。

2.八位ASCII碼,從第161個字元開始,後面的字元並不經常為用戶所使用,負值也未使用。GB2312編碼方式充分利用這一特性,將161-255(-95~-1)之間的數值空間作為漢字的標識碼。既然255-161 = 94不能滿足漢字容量的要求,就將每兩個字元並在一塊(即一個漢字佔兩個位元組),顯然,94* 94 =8836基本上已經滿足了常用漢字個數的要求。計算機處理字元時,當連續處理到兩個大與160(或-95~-1)的位元組時,就認為這兩個位元組存放了一個漢字字元。

2.兼容的基礎上編碼

這時,我們可以定義一個轉化規律,使得我們使得我們GB2312的存儲,可以兼容ASCII。就是使得高位位元組,和低位位元組都在(160——255)之間。

規則:

區位碼:漢字在 94×94 二維表中的位置,行(區)號,列 (位)

國標碼(交換碼):為了避開 ASCII 碼中的控制碼(00H-1FH),而與美標形象碼的範圍重合,。區位碼 的區號和位號都加上 32(十進位),16進位都加上(20h)

機內碼:漢英混合文本中,為了避免和單位元組的 ASCII 碼混 淆,交換碼的兩個位元組最高位都改為 1. 即是區位碼 區號和位號加上160( 十六進位下等於區位碼加上A0H)

下面以C程序展示:

#include<stdio.h>int main() { unsigned char a[100];//默認一個位元組8位全部是數字位,沒有符號位,因為漢字的GB2312是八位. printf("請輸入一些漢字
"); scanf("%s", a); for (int i = 0; a[i]; i = i + 2) { int c = a[i], b = a[i+1]; printf("%c%c:ASCII:%d,%d, 機內碼:%#X%X, 國標碼:%#X%X 區位碼:%d",c,b,c, b, c, b, (c - 128), (b - 128), (c - 160)); if (b < 170)printf("0%d", (b - 160)); else printf("%d
", (b- 160)); //printf("%c%c", 176161); } return 0;}

機內碼是ASCII碼的16進位。


推薦閱讀:

引得市缺字字體編碼方案說明
深度報文檢測基礎之編解碼
iOS KVO crash 自修復技術實現與原理解析
讓人困擾的Python 2編碼

TAG:編碼 | 自然語言處理 | C編程語言 |