漢字編碼問題


漢字編碼問題(轉)  摘自http://www.cnblogs.com/gaowg/articles/1101542.html


由於常常要和漢字處理打交道,因此,我常常受到漢字編碼問題的困擾。在不斷的打擊與堅持中,也積累了一點漢字編碼方面的經驗,想和大家一起分享。
一、漢字編碼的種類
漢字編碼中現在主要用到的有三類,包括GBK,GB2312和Big5。
1、 GB2312又稱國標碼,由國家標準總局發佈,1981年5月1日實施,通行於大陸。新加坡等地也使用此編碼。它是一個簡化字的編碼規範,當然也包括其他 的符號、字母、日文假名等,共7445個圖形字符,其中漢字佔6763個。我們平時說6768個漢字,實際上裏邊有5個編碼爲空白,所以總共有6763個 漢字。
 GB2312規定“對任意一個圖形字符都採用兩個字節表示,每個字節均採用七位編碼表示”,習慣上稱第一個字節爲“高字節”,第二個字節 爲“低字節”。GB2312中漢字的編碼範圍爲,第一字節0xB0-0xF7(對應十進制爲176-247),第二個字節0xA0-0xFE(對應十進制 爲160-254)。
GB2312將代碼表分爲94個區,對應第一字節(0xa1-0xfe);每個區94個位(0xa1-0xfe),對應第二 字節,兩個字節的值分別爲區號值和位號值加32(2OH),因此也稱爲區位碼。01-09區爲符號、數字區,16-87區爲漢字區 (0xb0-0xf7),10-15區、88-94區是有待進一步標準化的空白區。
2、Big5又稱大五碼,主要爲香港與臺灣使用,即是一個繁體 字編碼。每個漢字由兩個字節構成,第一個字節的範圍從0X81-0XFE(即129-255),共126種。第二個字節的範圍不連續,分別爲 0X40-0X7E(即64-126),0XA1-0XFE(即161-254),共157種。

3、GBK是GB2312的擴展,是向上兼容的,因此GB2312中的漢字的編碼與GBK中漢字的相 同。另外,GBK中還包含繁體字的編碼,它與Big5編碼之間的關係我還沒有弄明白,好像是不一致的。GBK中每個漢字仍然包含兩個字節,第一個字節的範 圍是0x81-0xFE(即129-254),第二個字節的範圍是0x40-0xFE(即64-254)。GBK中有碼位23940個,包含漢字 21003個。

表1 漢字編碼範圍

名稱    |       第一字節         |           第二字節
--------|-------------------------|------------------------
GB2312  |   0xB0-0xF7(176-247)   |    0xA0-0xFE(160-254)
--------|-------------------------|-------------------------
GBK0    |  x81-0xFE(129-254)    |  0x40-0xFE(64-254)
--------|-------------------------|-------------------------
Big5    |   0x81-0xFE(129-255)  |   0x40-0x7E(64-126),
       |                        |    0xA1-0xFE(161-254)
--------|-------------------------|------------------------


二、對漢字進行hash
爲了處理漢字的方便,在查找漢字的時候,我們通常會用到hash的方法,那怎麼來確定一個漢字位置呢?這就和每種編碼的排列有關了,這裏主要給出一種hash函數的策略。
對於GB2312編碼,設輸入的漢字爲GBword,我們可以採用公式(C1-176)*94 + (C2-161)確定GBindex。其中,C1表示第一字節,C2表示第二字節。具體如下:
   GBindex = ((unsigned char)GBword.at(0)-176)*94 + (unsignedchar)GBword.at(1) - 161;
   之所以用unsigned char類型,是因爲char是一個字節,如果用unsigendint,因爲int是4個字節的,所以會造成擴展,導致錯誤。
      對於GBK編碼,設輸入的漢字爲GBKword,則可以採用公式   index=(ch1-0x81)*190+(ch2-0x40)-(ch2/128),其中ch1是第一字節,ch2是第二字節。
具體的,
   GBKindex = ((unsigned char)GBKword[0]-129)*190 +
      ((unsigned char)GBKword[1]-64) - (unsignedchar)GBKword[1]/128;

三、怎樣判斷一個漢字的是什麼編碼
直接根據漢字的編碼範圍判斷,對於GB2312和GBK可用下面兩個程序實現。
1、判斷是否是GB2312
bool isGBCode(const string& strIn)
{
unsigned char ch1;
unsigned char ch2;

if (strIn.size() >= 2)
{
ch1 = (unsigned char)strIn.at(0);
ch2 = (unsigned char)strIn.at(1);
if (ch1>=176 && ch1<=247 &&ch2>=160 &&ch2<=254)
return true;
else return false;
}
else return false;
}
2、判斷是否是GBK編碼
bool isGBKCode(const string& strIn)
{
unsigned char ch1;
unsigned char ch2;

if (strIn.size() >= 2)
{
ch1 = (unsigned char)strIn.at(0);
ch2 = (unsigned char)strIn.at(1);
if (ch1>=129 && ch1<=254 &&ch2>=64 &&ch2<=254)
return true;
else return false;
}
else return false;
}

3、對於Big5
它的範圍爲:高字節從0xA0到0xFE,低字節從0x40到0x7E,和0xA1到0xFE兩部分。判斷一個漢字是否是 BIG5編碼,可以如上對字符的編碼範圍判斷即可。如何定位呢?那麼也想象所有編碼排列爲一個二維座標,縱座標是高字節,橫座標是低字節。這樣一行上的漢 字個數:(0x7E-0x40+1)+(0xFE-0xA1+1)=157。那麼定位算法分兩塊,爲:

if 0x40<=ch2<=0x7E: #is big5 char
index=((ch1-0xA1)*157+(ch2-0x40))*2
elif 0xA1<=ch2<=0xFE: #is big5 char
index=((ch1-0xA1)*157+(ch2-0xA1+63))*2

對於第二塊,計算偏移量時因爲有兩塊數值,所以在計算後面一段值時,不要忘了前面還有一段值。0x7E-0x40+1=63。

四、如果判斷一個字符是西文字符還是中文字符
大家知道西文字符主要是指ASCII碼,它用一個字節表示。且這個字符轉換成數字之後,該數字是大於0的,而漢字是兩個字節的,第一個字節的轉化爲數字之後應該是小於0的,因此可以根據每個字節轉化爲數字之後是否小於0,判斷它是否是漢字。
例如,設輸入字爲strin,則,
    If (strin.at(0) < 0)
      cout << ”是漢字” << endl;
    else cout << ”不是漢字” << endl;
五、下載GBK編碼表(見附件)
   下載GB2312編碼表見下面的回帖


--------------------------------------------------------------------------------
  另一些與編碼相關的文章:
1、GB碼和BIG5碼的互換技術
-------------------------------------------------------------------------
中文與英文用ASCII碼一個字節表示不同,它使用兩個字節來表示。事實上,在文本文件中保存的就是每個漢字對應的兩個字節編碼,而顯示問題由中文操作系統自動解決。
   漢字編碼並不統一,我們使用的是GB碼,而臺灣地區使用的是BIG5碼。BIG5碼文件中保存的是漢字相應的BIG5編碼,GB碼文件中保存的是漢字相應的GB編碼。所以轉換工作的關鍵是有一個記錄每個BIG5編碼對應GB編碼的碼錶文件。
   GB碼編碼規則是這樣的:每個漢字由兩個字節構成,第一個字節的範圍從0XA1-0XFE,共96種。第二個字節的範圍分別爲0XA1-0XFE,共96種。利用這兩個字節共可定義出 96 * 96=8836種漢字。實際共有6763個漢字。
   BIG5碼編碼規則是這樣的:每個漢字由兩個字節構成,第一個字節的範圍從0X81-0XFE,共126種。第二個字節的範圍分別爲 0X40-0X7E,0XA1-0XFE,共157種。也就是說,利用這兩個字節共可定義出 126 * 157=19782種漢字。這些漢字的一部分是我們常用到的,如一、丁,這些字我們稱爲常用字,其BIG5碼的範圍爲0XA440-0XC671,共 5401個。較不常用的字,如濫、調,我們稱爲次常用字,範圍爲 0XC940-0XF9FE,共7652個,剩下的便是一些特殊字符。
   製作碼錶文件的原理是這樣的:首先將所有的GB編碼寫入一個文件,然後,使用具有GB碼到BIG5碼轉換功能的軟件,如UCDOS下的CONVERT.EXE,將文件轉換爲BIG5碼文件,即得到碼錶文件。
   下面的程序可將全部國標碼寫入文件gb.txt(以下全部程序用foxpro書寫,可很容易的轉換成其他語言)
   fp = fopen("gb.txt",2)
   for i=161 to 247
     for j=161 to 254
       =fwrite(fp,chr(i)+chr(j))
     next
     =fwrite(fp,chr(13)+chr(10))
   next
   =fwrite(fp,chr(26))
   =fclose(fp)

   文件的組織形式:行對應編碼的第一字節,列對應編碼的第二字節。使用時請注意編碼的偏移量,如漢字“啊”GB編碼0xb1a1第一字節0xb1(177) 第二字節0xa1(161)所以他應該在文件的第(177-161=16)行第((161-161)*2=0)列。
   運行CONVERT.EXE將gb.txt轉換成BIG5碼的文件,這樣就可得到按GB碼組織的BIG5碼錶文件big5.txt。反之亦可得到按BIG5碼組織的GB碼錶文件。

   轉換的思路是這樣的:(用foxpro書寫)
   首先將碼錶文件裝入數組
   fp = fopen("big5.txt")
   i = 0
   do while feof(fp)
     i = i+1
     dime dict
     dict = fgets(fp)
   enddo
   =fclose(fp)
   其次將待轉換的文本裝入變量
   create cursor temp (mm m)
   append blank
   append memo mm from textfilename
   text = mm
   然後掃描文本,替換所有的GB編碼
   temp = ""
   i = 1
   do while i < len(text)
     ch = substr(text,i,1)
     if isascii(ch)   && 若是ASCII碼
       temp = temp+ch
       i = i+1
     else
       ch1 = substr(text,i+1,1)
       big5 =substr(dict[asc(ch)-161+1],(asc(ch1)-161)*2+1,2)
       temp = temp+big5
       i = i+2
     endif
   enddo
   最後將在temp中得到轉換後的文本

   需要注意的是,在foxpro中數組指針是以1開始,substr函數的起始位>=1。

--------------------------------------------------------------------------------
  一、GB2312-80介紹
GB2312碼是中華人民共和國國家漢字信息交換用編碼,全稱《信息交換用漢字編碼字符集--基本集》,由國家標準總局發佈,1981年5月1日實施,通行於大陸。新加坡等地也使用此編碼。
GB2312 收錄簡化漢字及符號、字母、日文假名等共7445個圖形字符,其中漢字佔6763個。GB2312規定“對任意一個圖形字符都採用兩個字節表示,每個字節 均採用七位編碼表示”,習慣上稱第一個字節爲“高字節”,第二個字節爲“低字節”。GB2312-80包含了大部分常用的一、二級漢字,和9區的符號。該 字符集是幾乎所有的中文系統和國際化的軟件都支持的中文字符集,這也是最基本的中文字符集。其編碼範圍是高位0xa1-0xfe,低位也是 0xa1-0xfe;漢字從0xb0a1開始,結束於0xf7fe。
GB2312將代碼表分爲94個區,對應第一字節(0xa1-0xfe);每 個區94個位(0xa1-0xfe),對應第二字節,兩個字節的值分別爲區號值和位號值加32(2OH),因此也稱爲區位碼。01-09區爲符號、數字 區,16-87區爲漢字區(0xb0-0xf7),10-15區、88-94區是有待進一步標準化的空白區。GB2312將收錄的漢字分成兩級:第一級是 常用漢字計3755個,置於16-55區,按漢語拼音字母/筆形順序排列;第二級漢字是次常用漢字計3008個,置於56-87區,按部首/筆畫順序排 列。故而GB2312最多能表示6763個漢字。
GB2312的編碼範圍爲2121H-777EH,與ASCII有重疊,通行方法是將GB碼兩個字節的最高位置1以示區別。
二、GB2312-80的擴展

GBK是GB2312-80的擴展,是向上兼容的。它包含了20902個漢字,其編碼範圍是0x8140-0xfefe,剔除高位0x80的字位。其所有字符都可以一對一映射到Unicode2.0。
GB18030-2000(GBK2K)在GBK的基礎上進一步擴展了漢字,增加了藏、蒙等少數民族的字形。GBK2K從根本上解決了字位不夠,字形不足的問題。它有幾個特點:
?它並沒有確定所有的字形,只是規定了編碼範圍,留待以後擴充。
?編碼是變長的,其二字節部分與GBK兼容;四字節部分是擴充的字形、字位,其編碼範圍是首字節0x81-0xfe、二字節0x30-0x39、三字節0x81-0xfe、四字節0x30-0x39。
?它的推廣是分階段的,首先要求實現的是能夠完全映射到Unicode3.0標準的所有字形。
?它是國家標準,是強制性的。
?現在還沒有任何一個操作系統或軟件實現了GBK2K的支持,這是現階段和將來漢化的工作內容。

三、Unicode編碼

國際標準組織於1984年4月成立ISO/IECJTC1/SC2/WG2工作組,針對各國文字、符號進行統一性編碼。1991年美國跨國公司成立 UnicodeConsortium,並於1991年10月與WG2達成協議,採用同一編碼字集。目前Unicode是採用16位編碼體系,其字符集內容 與ISO10646的BMP(BasicMultilingualPlane)相同。Unicode於1992年6月通過 DIS(DrafInternationalStandard),目前版本V2.0於1996公佈,內容包含符號6811個,漢字20902個,韓文拼音 11172個,造字區6400個,保留20249個,共計65534個。
隨着國際互聯網的迅速發展,要求進行數據交換的需求越來越大,不同的編碼體系越來越成爲信息交換的障礙,而且多種語言共存的文檔不斷增多,單靠代碼頁已很難解決這些問題,於是UNICODE應運而生。
UNICODE 有雙重含義,首先UNICODE是對國際標準ISO/IEC10646編碼的一種稱謂(ISO/IEC10646是一個國際標準,亦稱大字符集,它是 ISO於1993年頒佈的一項重要國際標準,其宗旨是全球所有文種統一編碼),另外它又是由美國的HP、Microsoft、IBM、Apple等大企業 組成的聯盟集團的名稱,成立該集團的宗旨就是要推進多文種的統一編碼。
UNICODE同現在流行的代碼頁最顯著不同點在於:UNICODE是兩字 節的全編碼,對於ASCII字符它也使用兩字節表示。代碼頁是通過高字節的取值範圍來確定是ASCII字符,還是漢字的高字節。如果發生數據損壞,某處內 容破壞,則會引起其後漢字的混亂。UNICODE則一律使用兩個字節表示一個字符,最明顯的好處是它簡化了漢字的處理過程。
UNICODE使用平面來描述編碼空間,每個平面分爲256行,256列,相對於兩字節編碼的高低兩個字節。
UNICODE的第一個平面,稱爲BasicMultilingualPlane(基本多文種平面),簡稱BMP,由於BMP僅用兩個字節表示,所以倍受青睞。


--------------------------------------------------------------------------------
  相關附件: (共 31517 字節)

[這個貼子最後由taozi在 2005/12/06 04:24pm 第 2 次編輯]

一些相關的網頁:
GBK代碼表:http://www.haiyan.com/steelk/navigator/ref/gbk/gbindex2.htm
GBK 漢字內碼擴展規範:http://www.haizhuedu.net/no-weiyischool/hzdwzx/xxzy/xxzy-kj/xxzy-xx/xkjs2-8/HAIZI/GBK.htm
下載GB2312編碼表,見附件
 

--------------------------------------------------------------------------------
  談談Unicode編碼,簡要解釋UCS、UTF、BMP、BOM等名詞
這是一篇程序員寫給程序員的趣味讀物。所謂趣味是指可以比較輕鬆地瞭解一些原來不清楚的概念,增進知識,類似於打RPG遊戲的升級。整理這篇文章的動機是兩個問題:
問題一:
使用Windows記事本的“另存爲”,可以在GBK、Unicode、Unicode big endian和UTF-8這幾種編碼方式間相互轉換。同樣是txt文件,Windows是怎樣識別編碼方式的呢?

我很早前就發現Unicode、Unicode big endian和UTF-8編碼的txt文件的開頭會多出幾個字節,分別是FF、FE(Unicode),FE、FF(Unicode big endian),EF、BB、BF(UTF-8)。但這些標記是基於什麼標準呢?

問題二:
最近在網上看到一個ConvertUTF.c,實現了UTF-32、UTF-16和UTF-8這三種編碼方式的相互轉換。對於 Unicode(UCS2)、GBK、UTF-8這些編碼方式,我原來就瞭解。但這個程序讓我有些糊塗,想不起來UTF-16和UCS2有什麼關係。
查了查相關資料,總算將這些問題弄清楚了,順帶也瞭解了一些Unicode的細節。寫成一篇文章,送給有過類似疑問的朋友。本文在寫作時儘量做到通俗易懂,但要求讀者知道什麼是字節,什麼是十六進制。

0、big endian和little endian
big endian和little endian是CPU處理多字節數的不同方式。例如“漢”字的Unicode編碼是6C49。那麼寫到文件裏時,究竟是將6C寫在前面,還是將49寫在前 面?如果將6C寫在前面,就是big endian。如果將49寫在前面,就是little endian。

“endian”這個詞出自《格列佛遊記》。小人國的內戰就源於吃雞蛋時是究竟從大頭(Big-Endian)敲開還是從小頭(Little-Endian)敲開,由此曾發生過六次叛亂,一個皇帝送了命,另一個丟了王位。

我們一般將endian翻譯成“字節序”,將big endian和little endian稱作“大尾”和“小尾”。

1、字符編碼、內碼,順帶介紹漢字編碼
字符必須編碼後才能被計算機處理。計算機使用的缺省編碼方式就是計算機的內碼。早期的計算機使用7位的ASCII編碼,爲了處理漢字,程序員設計了用於簡體中文的GB2312和用於繁體中文的big5。

GB2312(1980年)一共收錄了7445個字符,包括6763個漢字和682個其它符號。漢字區的內碼範圍高字節從B0-F7,低字節從A1-FE,佔用的碼位是72*94=6768。其中有5個空位是D7FA-D7FE。

GB2312支持的漢字太少。1995年的漢字擴展規範GBK1.0收錄了21886個符號,它分爲漢字區和圖形符號區。漢字區包括21003個字符。

從ASCII、GB2312到GBK,這些編碼方法是向下兼容的,即同一個字符在這些方案中總是有相同的編碼,後面的標準支持更多的字符。在這些編 碼中,英文和中文可以統一地處理。區分中文編碼的方法是高字節的最高位不爲0。按照程序員的稱呼,GB2312、GBK都屬於雙字節字符集(DBCS)。

2000年的GB18030是取代GBK1.0的正式國家標準。該標準收錄了27484個漢字,同時還收錄了藏文、蒙文、維吾爾文等主要的少數民族 文字。從漢字字彙上說,GB18030在GB13000.1的20902個漢字的基礎上增加了CJK擴展A的6582個漢字(Unicode碼 0x3400-0x4db5),一共收錄了27484個漢字。

CJK就是中日韓的意思。Unicode爲了節省碼位,將中日韓三國語言中的文字統一編碼。GB13000.1就是ISO/IEC 10646-1的中文版,相當於Unicode 1.1。

GB18030的編碼採用單字節、雙字節和4字節方案。其中單字節、雙字節和GBK是完全兼容的。4字節編碼的碼位就是收錄了CJK擴展A的 6582個漢字。 例如:UCS的0x3400在GB18030中的編碼應該是8139EF30,UCS的0x3401在GB18030中的編碼應該是8139EF31。

微軟提供了GB18030的升級包,但這個升級包只是提供了一套支持CJK擴展A的6582個漢字的新字體:新宋體-18030,並不改變內碼。Windows 的內碼仍然是GBK。

這裏還有一些細節:

GB2312的原文還是區位碼,從區位碼到內碼,需要在高字節和低字節上分別加上A0。

對於任何字符編碼,編碼單元的順序是由編碼方案指定的,與endian無關。例如GBK的編碼單元是字節,用兩個字節表示一個漢字。 這兩個字節的順序是固定的,不受CPU字節序的影響。UTF-16的編碼單元是word(雙字節),word之間的順序是編碼方案指定的,word內部的 字節排列纔會受到endian的影響。後面還會介紹UTF-16。

GB2312的兩個字節的最高位都是1。但符合這個條件的碼位只有128*128=16384個。所以GBK和GB18030的低字節最高位都可能 不是1。不過這不影響DBCS字符流的解析:在讀取DBCS字符流時,只要遇到高位爲1的字節,就可以將下兩個字節作爲一個雙字節編碼,而不用管低字節的 高位是什麼。

2、Unicode、UCS和UTF
前面提到從ASCII、GB2312、GBK到GB18030的編碼方法是向下兼容的。而Unicode只與ASCII兼容(更準確地說,是與ISO-8859-1兼容),與GB碼不兼容。例如“漢”字的Unicode編碼是6C49,而GB碼是BABA。

Unicode也是一種字符編碼方法,不過它是由國際組織設計,可以容納全世界所有語言文字的編碼方案。Unicode的學名 是"UniversalMultiple-Octet Coded Character Set",簡稱爲UCS。UCS可以看作是"Unicode Character Set"的縮寫。

根據維基百科全書(http://zh.wikipedia.org/wiki/)的記載:歷史上存在兩個試圖獨立設計Unicode的組織,即國 際標準化組織(ISO)和一個軟件製造商的協會(unicode.org)。ISO開發了ISO 10646項目,Unicode協會開發了Unicode項目。

在1991年前後,雙方都認識到世界不需要兩個不兼容的字符集。於是它們開始合併雙方的工作成果,併爲創立一個單一編碼表而協同工作。從Unicode2.0開始,Unicode項目採用了與ISO 10646-1相同的字庫和字碼。

目前兩個項目仍都存在,並獨立地公佈各自的標準。Unicode協會現在的最新版本是2005年的Unicode 4.1.0。ISO的最新標準是ISO10646-3:2003。

UCS只是規定如何編碼,並沒有規定如何傳輸、保存這個編碼。例如“漢”字的UCS編碼是6C49,我可以用4個ascii數字來傳輸、保存這個編 碼;也可以用utf-8編碼:3個連續的字節E6 B1 89來表示它。關鍵在於通信雙方都要認可。UTF-8、UTF-7、UTF-16都是被廣泛接受的方案。UTF-8的一個特別的好處是它與ISO- 8859-1完全兼容。UTF是“UCS Transformation format”的縮寫。

IETF的RFC2781和RFC3629以RFC的一貫風格,清晰、明快又不失嚴謹地描述了UTF-16和UTF-8的編碼方法。我總是記不得 IETF是Internet Engineering Task Force的縮寫。但IETF負責維護的RFC是Internet上一切規範的基礎。

2.1、內碼和code page
目前Windows的內核已經支持Unicode字符集,這樣在內核上可以支持全世界所有的語言文字。但是由於現有的大量程序和文檔都採用了某種特定語言的編碼,例如GBK,Windows不可能不支持現有的編碼,而全部改用Unicode。

Windows使用代碼頁(code page)來適應各個國家和地區。code page可以被理解爲前面提到的內碼。GBK對應的code page是CP936。

微軟也爲GB18030定義了code page:CP54936。但是由於GB18030有一部分4字節編碼,而Windows的代碼頁只支持單字節和雙字節編碼,所以這個code page是無法真正使用的。

3、UCS-2、UCS-4、BMP
UCS有兩種格式:UCS-2和UCS-4。顧名思義,UCS-2就是用兩個字節編碼,UCS-4就是用4個字節(實際上只用了31位,最高位必須爲0)編碼。下面讓我們做一些簡單的數學遊戲:

UCS-2有2^16=65536個碼位,UCS-4有2^31=2147483648個碼位。

UCS-4根據最高位爲0的最高字節分成2^7=128個group。每個group再根據次高字節分爲256個plane。每個plane根據第 3個字節分爲256行 (rows),每行包含256個cells。當然同一行的cells只是最後一個字節不同,其餘都相同。

group 0的plane 0被稱作Basic Multilingual Plane, 即BMP。或者說UCS-4中,高兩個字節爲0的碼位被稱作BMP。

將UCS-4的BMP去掉前面的兩個零字節就得到了UCS-2。在UCS-2的兩個字節前加上兩個零字節,就得到了UCS-4的BMP。而目前的UCS-4規範中還沒有任何字符被分配在BMP之外。

4、UTF編碼

UTF-8就是以8位爲單元對UCS進行編碼。從UCS-2到UTF-8的編碼方式如下:

UCS-2編碼(16進制) UTF-8 字節流(二進制)
0000 - 007F 0xxxxxxx
0080 - 07FF 110xxxxx 10xxxxxx
0800 - FFFF 1110xxxx 10xxxxxx 10xxxxxx

例如“漢”字的Unicode編碼是6C49。6C49在0800-FFFF之間,所以肯定要用3字節模板了:1110xxxx10xxxxxx 10xxxxxx。將6C49寫成二進制是:0110 110001 001001, 用這個比特流依次代替模板中的x,得到:1110011010110001 10001001,即E6 B1 89。

讀者可以用記事本測試一下我們的編碼是否正確。需要注意,UltraEdit在打開utf-8編碼的文本文件時會自動轉換爲UTF-16,可能產生混淆。你可以在設置中關掉這個選項。更好的工具是Hex Workshop。

UTF-16以16位爲單元對UCS進行編碼。對於小於0x10000的UCS碼,UTF-16編碼就等於UCS碼對應的16位無符號整數。對於不 小於0x10000的UCS碼,定義了一個算法。不過由於實際使用的UCS2,或者UCS4的BMP必然小於0x10000,所以就目前而言,可以認爲 UTF-16和UCS-2基本相同。但UCS-2只是一個編碼方案,UTF-16卻要用於實際的傳輸,所以就不得不考慮字節序的問題。

5、UTF的字節序和BOM
UTF-8以字節爲編碼單元,沒有字節序的問題。UTF-16以兩個字節爲編碼單元,在解釋一個UTF-16文 本前,首先要弄清楚每個編碼單元的字節序。例如“奎”的Unicode編碼是594E,“乙”的Unicode編碼是4E59。如果我們收到UTF-16 字節流“594E”,那麼這是“奎”還是“乙”?

Unicode規範中推薦的標記字節順序的方法是BOM。BOM不是“Bill OfMaterial”的BOM表,而是Byte Order Mark。BOM是一個有點小聰明的想法:

在UCS編碼中有一個叫做"ZERO WIDTH NO-BREAKSPACE"的字符,它的編碼是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來表明編碼方式。字符"ZEROWIDTH NO-BREAK SPACE"的UTF-8編碼是EF BB BF(讀者可以用我們前面介紹的編碼方法驗證一下)。所以如果接收者收到以EF BB BF開頭的字節流,就知道這是UTF-8編碼了。

Windows就是使用BOM來標記文本文件的編碼方式的。

6、進一步的參考資料
本文主要參考的資料是 "Short overview of ISO-IEC 10646 andUnicode" (http://www.nada.kth.se/i18n/ucs/unicode-iso10646-oview.html)。

我還找了兩篇看上去不錯的資料,不過因爲我開始的疑問都找到了答案,所以就沒有看:

"Understanding Unicode A general introduction to the UnicodeStandard" (http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&item_id=IWS-Chapter04a)
"Character set encoding basics Understanding character set encodings andlegacy encodings"(http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&item_id=IWS-Chapter03)
我寫過UTF-8、UCS-2、GBK相互轉換的軟件包,包括使用WindowsAPI和不使用Windows API的版本。以後有時間的話,我會整理一下放到我的個人主頁上(http://fmddlmyy.home4u.china.com)。

我是想清楚所有問題後纔開始寫這篇文章的,原以爲一會兒就能寫好。沒想到考慮措辭和查證細節花費了很長時間,竟然從下午1:30寫到9:00。希望有讀者能從中受益。

附錄1 再說說區位碼、GB2312、內碼和代碼頁
有的朋友對文章中這句話還有疑問:
“GB2312的原文還是區位碼,從區位碼到內碼,需要在高字節和低字節上分別加上A0。”

我再詳細解釋一下:

“GB2312的原文”是指國家1980年的一個標準《中華人民共和國國家標準 信息交換用漢字編碼字符集 基本集 GB 2312-80》。這個標準用兩個數來編碼漢字和中文符號。第一個數稱爲“區”,第二個數稱爲“位”。所以也稱爲區位碼。1-9區是中文符號,16-55 區是一級漢字,56-87區是二級漢字。現在Windows也還有區位輸入法,例如輸入1601得到“啊”。(這個區位輸入法可以自動識別16進制的 GB2312和10進制的區位碼,也就是說輸入B0A1同樣會得到“啊”。)

內碼是指操作系統內部的字符編碼。早期操作系統的內碼是與語言相關的。現在的Windows在系統內部支持Unicode,然後用代碼頁適應各種語言,“內碼”的概念就比較模糊了。微軟一般將缺省代碼頁指定的編碼說成是內碼。

內碼這個詞彙,並沒有什麼官方的定義,代碼頁也只是微軟這個公司的叫法。作爲程序員,我們只要知道它們是什麼東西,沒有必要過多地考證這些名詞。

所謂代碼頁(code page)就是針對一種語言文字的字符編碼。例如GBK的code page是CP936,BIG5的code page是CP950,GB2312的code page是CP20936。

Windows中有缺省代碼頁的概念,即缺省用什麼編碼來解釋字符。例如Windows的記事本打開了一個文本文件,裏面的內容是字節流:BA、BA、D7、D6。Windows應該去怎麼解釋它呢?

是按照Unicode編碼解釋、還是按照GBK解釋、還是按照BIG5解釋,還是按照ISO8859-1去解釋?如果按GBK去解釋,就會得到“漢 字”兩個字。按照其它編碼解釋,可能找不到對應的字符,也可能找到錯誤的字符。所謂“錯誤”是指與文本作者的本意不符,這時就產生了亂碼。

答案是Windows按照當前的缺省代碼頁去解釋文本文件裏的字節流。缺省代碼頁可以通過控制面板的區域選項設置。記事本的另存爲中有一項ANSI,其實就是按照缺省代碼頁的編碼方法保存。

Windows的內碼是Unicode,它在技術上可以同時支持多個代碼頁。只要文件能說明自己使用什麼編碼,用戶又安裝了對應的代碼頁,Windows就能正確顯示,例如在HTML文件中就可以指定charset。

有的HTML文件作者,特別是英文作者,認爲世界上所有人都使用英文,在文件中不指定charset。如果他使用了0x80-0xff之間的字符, 中文Windows又按照缺省的GBK去解釋,就會出現亂碼。這時只要在這個html文件中加上指定charset的語句,例如:
<meta http-equiv="Content-Type" content="text/html;charset=ISO8859-1">
如果原作者使用的代碼頁和ISO8859-1兼容,就不會出現亂碼了。

再說區位碼,啊的區位碼是1601,寫成16進制是0x10,0x01。這和計算機廣泛使用的ASCII編碼衝突。爲了兼容00-7f的ASCII 編碼,我們在區位碼的高、低字節上分別加上A0。這樣“啊”的編碼就成爲B0A1。我們將加過兩個A0的編碼也稱爲GB2312編碼,雖然GB2312的 原文根本沒提到這一點。


--------------------------------------------------------------------------------
  一、幾個基本概念
  1、bit 與  byte
  bite 是二進制的即0和1,譯作比特。
  Byte是指八個bit,代表一個Ansi或Ascii 代碼,即一個英文字母,譯作字節。由於漢字使用了16位(比特)代碼,所以稱爲雙字節。
  其換算關係很簡單,一byte等於八bit。
  2,ANSI碼,ANSI是(AmericanNational Standard Institude)的簡寫。ANCII是American Standard Code for Information Interchange的簡寫。
   ANSI是以標準的八位來顯示一個字符的,可以代表256字。基本上包括了拉丁語系中所需要的全部字符。起初美國人認爲7位(比特)就足夠了,因爲2的 7次方等於128,而英文字母只有26個,大小寫加一起52個,再加上十個數字,幾個標點和數學運算符號,也夠了。所以就制定了ANCII七位的代碼系 統,這七位的代碼系統的128位與ANSI的256中的前128完全一致,加之現在的計算機系統都能自動分別,所以,這兩個概念也就不太分別了。
  二、GB 2312 漢字編碼字符集
GB2312 碼是中華人民共和國國家標準漢字信息交換用編碼,全稱《信息交換用漢字編碼字符集?基本集》,標準號爲GB 2312—80(GB是“國標”二字的漢語拼音縮寫),由國家標準總局發佈,1981年5月1 日實施。習慣上稱國標碼、GB碼,或區位碼。它是一個簡化字漢字的編碼,通行於中國大陸地區。新加坡等地也使用這一編碼。
  GB 2312—80收錄簡化漢字及一般符號、序號、數字、拉丁字母、日文假名、希臘字母、俄文字母、漢語拼音符號、漢語注音字母,共7445個圖形字符。其中 漢字以外的圖形字符682個,漢字6763個。由於6763比那GB 2312-80要好記得多,尤其是在GBK也流行的時代,人們總是習慣用6763來代指那通行(同時也讓我們痛苦了)若干年的字符系統。
  GB 2312-80規定,“對任意一個圖形字符都採用兩個字節(Byte)表示。每個字節均採用GB 1988-80及GB 2311-80中的七位編碼表示。兩個字節中前面的字節爲第一字節,後面的字節爲第二字節。”習慣上稱第一字節爲“高字節”(Upper),第二字節爲 “低字節”(low)。
  GB 2312-80將代碼分爲94個區(Section),對應第一字節,每個區94個位(Position),對應第二字節。兩個字節的值,分別爲區號值和位號值各加32(20H)。我們通常所說的區位便由此而來。
   GB 2312-80規定,01~09區(原規定爲1~9區,爲表示區位碼方便起見,現改稱01~09區)爲符號、數字區,16~87區爲漢字區。而10~15 區、88~94區是有待於“進一步標準化”的“空白位置”區域。便第10區推薦與第3區的94個圖形字符(即GB1988-80中的94個圖形字符)相 同,字形寬度爲其寬度的一半。)
  GB 2312-80把收錄的漢字分成兩級。第一級漢字是常用漢字,計3755個,置於16~55區,按漢語拼音字母/筆形順序排列;第二級漢字是次常用漢字, 計3008個,置於56~87區,按部首/筆區順序排列。字音以普通話審音委員會發表的《普通話導讀詞三次審音總表初稿》(1963年出版)爲準,字形以 中華人民共和國文化部、中國文字改革委員會公佈的《印刷通用漢字字形表》(1964年出版)爲準。
  例:漢字“啊”,第一字節爲0110000,第二字節爲0100001,即16區、01位,用16。
這 些字的來源我不知道是根據什麼,但就我處理文獻的情況看,有些是對很常用的字,如用於人名的“璟”字,一是明代著名戲曲理論家“沈璟”,一是南唐中主(同 時又是文學家)“李璟”,出現頻率比較高,但卻沒有收在6763之中,而象“芏”“塄”“鎣”等近千字幾乎用不上的字卻佔據着極緊張的資源。
  以後的GBK更有這種情況。
  三、GB/T12345 漢字編碼字符集
  GB/T12345和GB2312一樣,是中華人民共和國國家標準漢字信息交換用編碼,全稱《信息交換用漢字編碼字符集輔助集》,標準號爲GB/T12345-90,中華人民共和國國家技術監督局1990年6月13日發佈,1990年12月1日實施。
   GB/T12345-90是一個關於繁體漢字的編碼標準。所謂“輔助集”,?是與“基本集”(GB2312-80)相對應而言。即:GB/T12345 是“與GB2312相對應的圖形字符集。原則上,本字符集是將GB2312中的簡化字用相應的繁體字替換而成。因此,這些替代的繁體字具有與被替代的簡化 字相同的編碼;未曾簡化的漢字以及非漢字圖形字符,仍是GB2312中的漢字及圖形字符,並具有與之相同編碼。”
  關於繁體字替換簡化字的原 則,GB/T12345註明:“本標準原則是按照《簡化字總表》中所列繁體字與簡化字的對應關係進行替換。”《簡化字總表》由中國文字改革委員會1964 年5月發表,後經國家語言文字工作委員會作個別修訂,國務院1986年6月4日批准重新發表。
  除了以上的根本差異外,GB/T12345與GB2312的區別還有以下幾點:1,增補了個別圖形字符,共收錄7583個圖形字符:漢字以外的圖形字符716個,漢字6866個(其中一級漢字3755個,二級漢字3008個,增補漢字103個。)
  a,“根據排版需要,增補了豎排標點符號29個,這些字符增補於6區57位至85位。”
  b,“根據GB5007.1(《信息交換用漢字24×24點陣字模集》),增加了6個漢語拼音用圖形字符,這些字符增補於8區27位至32位。”
   c,“GB2312中,由於60年代漢字簡化被精簡的字有103個,這些被精簡的字根據繁體字處理系統的需要增補於88~89區。”所謂精簡,即廢除某 個繁體字,而用另一個字代替,如廢除“雲”字,而以“雲”字代替。由此形成一個簡化字對應兩個或兩個以上繁體字的現象。
  2,GB/T12345規定的在七位環境中指明圖形字符集的轉義序列不同,同時規定了在八位環境中的轉義序列。
   GB/T12345沒有指明其字符集字形依據,便它使用的繁體漢字,與《簡化字總表》中所使用的字形一致。其絕大多數漢字,使用了“新字形”。例如, “產”的繁體字,它使用了新字形“產”,而不自舊字形“產”。因此,一些舊字形與新字形的差異,被視爲字形的差異(異體字),而不是繁體與簡體的差異。 如:收錄“奐”“換”“喚”,而不用“奐”“換”“喚”,即因爲“奐”是舊字形,而非繁體字。但是其中極個別字又使用了舊字形,如“爲”“僞”的繁體字, 使用了舊字形“爲”“僞”,而上用新字形“為”“偽”。關於新舊字形,可參見中國社會科學院語言研究所編纂的《現代漢語詞典》(商務印書館1978年第一 版)、《新華字典》(商務印書館1979年修訂版)所附的《新舊字形對照表》,以及辭海編輯委員會編纂的《辭海》(上海辭書出版社1979年出版)所附的 《新舊字形對照舉例》。
關於被精簡的漢字:
  1,88~89區所列的103個漢字,GB/T12345稱爲“60年代漢字簡化時被精簡 的字。”,這一表達不完全準確。例如:,“豐”與“豐”,漢字簡化時精簡了“豐”字,以“豐”字替代,而GB/T12345將被精簡的“豐”字,作爲 “豐”的繁體,置於23~65,而將“豐”字置於88~19。類似的情況佔其103字的三分之一左右。
  2,所謂103個“被精簡的漢字”,只 是被精簡的“繁體字”,而未包括被精簡(廢除)的“異體字”。例如,“昇”和“陞”,作爲“升”的異體字,被停止使用,GB/T12345亦未收錄。相關 的法定文件爲中華人民共和國文化部、中國文字改革委員會1955年6月發佈的《第一批異體字整理表》,該表列出異體字810組,1865字,並規定廢除異 體字1055個。一些異體字,習慣上也被看作是簡化字,所以,《簡化字總表》特地從《第一批異體字整理表》中選出39個異體字,列爲附錄。
   3,按照漢字簡化原則,在容易引起歧義時不簡化。例如“餘”和“餘”,《簡化字總表》對“餘”字的腳註說;“在餘和餘意義可能混淆時,仍用餘,如文言句 “餘年無多”。同時,有些漢字只簡化其字義的某一個或幾個義項,如徵,在象徵等義項上被簡化爲徵,而在音樂調值的義項上(即宮商角徵羽的徵,讀作 zhi[止]),並不簡化。因此在GB2312中,保留了個別繁體(或異體)字,也就是說,同時收錄了一個字的簡體和繁體(或異體),這包括“幹乾、後 後、夥夥、麼麼、於於、餘餘、折摺、徵徵”等。作爲與GB2312對應的繁體編碼,GB/T12345在這些字上處理較混亂。例如:GB/T12345將 “夥”置於27-79,“夥”置於66-23,與GB2312編碼相同,即,以“夥”對應“夥”,以“夥”對應“夥”。另一種情況是,GB/T12345 將“後”置於26-83,對應GB2312的“後”,將“後”置於65-65,對應GB2312的“後”;將“徵”置於53-87,對應GB2312的 “徵”,將“徵”置於65-71,對應GB2312的“徵”,顯然不當。
  注:
  1,以上代碼表,除06、08區增補符號用GIF圖形編制外,其他均使用GBK代碼編制,只有在你的電腦能完全正確GBK漢字時,才能保證看到的上表與GB/T12345標準印刷件(中國標準出版社1991年10月版)相同的字形。
   2,儘管滿足查看GBK漢字的條件,仍有兩個漢字的顯示,與GB/T12345標準印刷件有所差異。兩個字的代碼爲47-22、80-89。第一字的印 刷件字形,未列入有關簡化字的法定文件,但習慣上被視爲“隙”的繁體,而GBK編碼未收錄此字,無法顯示,故以“隙”替代。第二字的印刷件字形,系對應簡 體“瘞”,按照《簡化字總表》第二表《可作簡化偏旁的簡化字和簡化偏旁》,“夾”簡化爲“夾”,所以,“瘞”對應的繁體字,應該是“瘞”,同時,印刷件上 的此字不見於字書,因此它可能是排版時錯誤,故上表使用了“瘞”字。
  3,01~15區的符號和空白位置,除增補者以外,與GB2312的符號、編碼位置完全相同。
 
--------------------------------------------------------------------------------
  四、BIG-5字符集
  BIG-5碼是通行於臺灣、香港地區的一個繁體字編碼方案,俗稱“大五碼”。它並不是一個法定的編碼方案,存在着一些瑕疵,業界的評價也不高,但它廣泛地被應用於電腦業,尤其是在國際互聯網中,從而成爲一種事實上的行業標準。
  關於BIG-5碼的背景,一直未見詳細記載,簡單介紹如下:
   1983年10月,臺灣國家科學委員會、教育部漢字推行委員會、中央標準局、行政院主計處電子資料處理中心共同制定了《通用漢字標準交換碼》 (chinese  Ideographic standard  code for  information  interchange ,簡稱CISCII碼),經試用修訂,1986年8月4日由臺灣中央標準局公佈爲法定標準,標準編號爲CNS 11643。這一標準於1992年5月21日重新修訂公佈,更名爲《中文標準交換碼》(chinese standard  interchange  code).1995mm 1 月4日,臺灣中央標準局又公佈了CNS 11643-1《中文標準交換碼使用方法》。
  BIG-5碼是1984年臺灣信息工業促進會根據《通用漢字標準交換碼》制訂的編碼方案。至於爲何稱爲“BIG-5”。
  BIG-5碼是一個雙字節編碼方案,其第一字節的值在16進制的AO~FE之間,第二字節在40~7E和A1~FE之間。因此,其第一字節的最高位是1,第二字節的最高位則可能是1,也可能是0。
BIG-5碼的圖形符號及漢字,基本與CNS 11643標準的第一、第二字面(Plane)一致,它收錄13461個符號和漢字,包括:
  1,符號408個,編碼位置爲A140~A3FE(實際止於A3BF,末尾有空白位置。)
  2,漢字13053個,分爲常用字和次常用字兩部分,各部分中的漢字按筆劃/部首排列。其中:
  a,常用字5401個,編碼位置爲A440~C67E。包括臺灣教育部頒佈的《常用漢字標準字體表》中的全部漢字4808個,臺灣國中國小教科書常用字587個,異體字6個。
B,次常用字7652個,編碼位置爲C940~F9FE(實際止於F9D5,末尾有空白位置)。包括臺灣教育部《次常用漢字標準字體表》的全部漢字6341個,《罕用漢字標準字體表》中使用頻率較高的字1311個。
  其餘的A040~A0FE、C6A1`FEFE爲空白區域。一些空白位置,經常被用於用戶造字區,而且多存放香港常用字和粵語方言字。
   現在流行的BIG-5碼字庫,在F9D6~F9DC位置大都有7個常用字,據說爲倚天系統所增。若計此7字,則全數爲13060個漢字,13468個漢 字和符號。此外,一些BIG-5碼字庫,如Windows繁體中文版的True Type細明體(華康科技提供,2.0版),在F9DD~F9FE位置還有33個製表符和1個“■”符號。
  五,BIG5+碼
  1,編訂BIG5+碼之緣起
臺灣行政院協助解決衆多使用BIG5碼政府單位於進行公文電子傳遞時寓到自造字無法轉換CNS問題,而於數次會商後決議成立專案委託中文電腦基金會辦理[BIG5碼字集擴編計劃],86年7月擴編完成。
  2,編碼原則
BIG5+ 碼系以CNS爲藍本,共增編標準字集4760個字符與推薦字集3250個字符;其標準字集即納編CNS第3字面字集內之4145個,第4個字面字集內之 219個字,均爲一般文書常用之中文字,如推廣應用於研究發新版中文軟體,則估計可解決80%的BIG5自造字轉換CNS交換碼問題。
(一),長度仍爲雙字節,即高字節之第一位元(MSB)=1。
(二),保留原有之標準字集字區及使用者加字區,使與原有系統具相容性。
(三),以國家標準(CNS11643)及國際標準(ISO10646)字集爲字源範圍,並依CNS之序編入。
(四)包含於ISO10646或CNS11643字集內且市面已廣爲使用之倚天自造字及符號,編入標準字集並保留原碼位。
(五),單獨成字之部首不再重覆編碼(如金、木、水、火、土)。
(六),有重複的字刪除其後者,錯字則依CNS修正之。
  3,字碼架構
(一),總碼位:由原有之19782個擴大爲23940個(高字節爲81-FE,低位元組爲40-7E、80-FE)。
(二)編碼區間
   a,第一標準字集:此區即原BIG-5碼標準字集但刪除22個重字,編碼範圍爲A140-F9FE(高字節爲A1-F9,低字節爲40-7E、A1- FE)。共有13973個字符,包括常用漢字5401個(A440-C67E),次常用漢字7693個(C940-F9D5)及符號471個(A140- A3FE)、字符408個(C6A1-C8FE)。
  b,第二標準字集:此區即擴編部分,編碼範圍爲8180-FEA0(高字節爲81-F9,低字節爲80-A0)。共收編罕用漢字4158個。
   c,CMEX推薦字集:因BIG-5碼系統之編碼位置有限,未能編入第一及第二標準字集之較常用罕用及異體漢字、簡體字與日韓漢字3454個,經中推會 (CMEX)建議集中收編於此區。編碼範圍爲原造字區之8140-83FE、8E40-A0FE(高字節爲81-83、8E-A0,低字節爲40—7E、 A1-FE)。
  d,造字區:僅使用第二標準字集時,仍保留5809個碼位供使用者造字,可編碼區間不變;但同時使用推薦字集時,因BIG5+ 碼之推薦字集系使用原造字區之8140-83FE及8E40-A0FE,供造字之碼位僅餘2355個,可編碼區間爲FA40-FEFE(785個碼位)、 8440-8DFE(1570個碼位)。
  e,使用者專用字集:爲使各行業專用之字集亦能進行信息交換,向中推會申請登記ID後,將ID字形等依照 輸規定傳出供對方顯示或列印。
  使用者專用字集之編碼區與CMEX推薦字集相同,亦使用到原造字區。
  4,可用之工具
(一),24*24點陣字形檔。
(二),注音符號、倉頡碼屬性檔。
(三),CNS11643、ISO10646碼對照檔。
(四),BIG5+〈——〉ISO10646轉碼程序。
(五),BIG5+〈——〉CNS11643轉碼程序。
(六)BIG-5碼自造字轉BIG-5碼管理程序。
(七)BIG-5自造字轉碼程序。
  5,使用方法
  因BIG5+碼在標準字集外尚提供推薦字集,各單位可依自己原有造字情況選擇適當之使用方法:
  (一)字集之使用1.以下情可使用全字集(即第一、第二標準字集及推薦字集,共21585個字符)
(1),全無自造字者。
(2),原來已有自造字,其編碼區間未與推薦字集重疊者,(即FA40—FEFE及8440-8DFE以外)
(3),原來已有自造初開球編碼區間雖與推薦字集重疊,但可全部轉換爲新碼者。
(4),原來已有自造字,但經轉換爲新碼後剩餘自造字未超過2355個,且可以或原意改置於FA40-FEFE及8440-8DFE以外者。2.以下情況僅使用標準字集(即第一與二標準字集,共13461個字符):
(1),有自造字,但轉碼後剩餘自造字仍超過2355個者。
(2),原有自造字聳部或部分落於FA40-8440-8DFE兩個造字區(推薦字集使用範圍)內,不易或不願轉換爲新碼者。
(二)字形轉輸與交換規格之使用
BIG- 5碼雖已擴編,但其餘未能納入自造字及未來不斷新增之自造字,依舊會產生交換及傳送問題;爲使這些自造字於網路傳輸及檔案交換時,仍可作字形顯示與列印, 特訂定以下幾項規格:1,文件檔案交換傳輸規格,依SGML(ISO8879)格式及CNS(ISO9541)字形資訊交換規格,訂定SGML文件檔案內 字形應含之參數。2,中文周邊裝置字形下載規格:包括中文終端機、打印機及其他終端設備,系依CNS13479(ISO6429)規範訂定字形下載之規 格。
(三)用戶需準備之工作
BIG-5碼編擴編後納入之自造字,如不作轉碼,將來交換時一定會發生一字兩碼的問題,因此在BIG5+碼之 新版中文系統軟體推出前,用戶必需先轉換現在自造字之舊碼,其程序如下:1,建立自造字之舊碼與擴編後新碼對照表:各單位之造字區管理者可利用第六項工具 [BIG5自造字轉標準字對照表管理程式]比對造字區內自造字後建立單位內新/舊碼對照表。2,清查需要轉碼之資料檔:各單位或集中或各自處理,均必需先 清查所有用過原造字區字碼之料檔,以備進行轉碼。3,自造字舊碼之轉換:各項業務負責人或各使用者可利用第七項工具[BIG5自造字轉標準字轉換程式]及 所建立之單位內新/舊碼對照表,將所有的[文字檔(.txt。)原用之自編舊碼轉換爲BIG5+新碼。4,單位內造字區之重整;爲避免轉碼後發生一字兩碼 之現象,各單位原有之造字區應作整理,刪除已編入BIG5+碼系統者,其餘自造字則保留原編碼或重新編碼(重整造字區)。
6,應用現況
臺灣廠商如:芙蓉坊、昌泰科枝、大同、倚天等公司已將BIG5+碼應用於新產品中。

六、臺灣制定的CNS11643
  1,編訂中文標準交換碼之緣起
  72年10月由臺灣科學委員會、教育部、中央標準局及本中心 合編[通用漢字標準交換碼]後決議試用二年;試用期滿,經檢討修正重編並向中央標準局申請訂爲國家標準,75年8月4日獲該局審定公佈國家標準,編號 [CNS11643];81年51 21日再由該局因應實際需要修訂擴編,並更名爲[中文標準交換碼(chinesestandard interchange code)]。
  2,CNS11643之適用範圍
  本標準適用於中文信息之處理。
  3,編碼之各項考慮
  中文信息標準交換碼是否能普遍地推廣使用,使一般使用者共同樂意接受,端視其是否具有實用性,因此本碼之編碼原則研訂時,曾先就標準碼的結構、編碼需求等作多方面的周密考慮。
  (一),以教育部所公佈的四個字體表之字集爲範圍。
  (二),根據使用的頻率及範圍,整理後分別編排於各個字面,以適應各個層次之使用者。
  (三),符合國際信息傳輸上所使用之CNS5205[信息處理及交換用七位碼字符集]及CNS7654[信息處理-七位及八位碼字符集-延碼技術]標準通信定則。
  (四)涵蓋常用之外語字母及工商界與學校所使用之文字及符號。
  4,字集編排原則
  (一),中文標準交換碼分爲十六個字面,每個字面可陳列94列*94行,即8836個字符。目前第一至第七字面列有字集,第八至第十一字面預留擴編之用;第十二至第十六字面則爲使用者加字區,凡未收於本碼系統之中文及符號,他用者可視需要自行編訂於加字區使用。
  總支持文字量達141376個。
   (二)各字面字集排列大抵依使用頻率爲次序,每一字面以常用字爲主,第二字面以次常用字爲主,第三字面以部分罕用字及較常用異體字爲主,第四字面以 ISODIS10646第二版之漢字、各單位/信息業用字及戶政用字爲主,第五字面以罕用字爲主,第六、第七字面以異體字爲主。其中第一第二字面字集先於 民國七十五年八月四日公佈爲國家標準。
  5,字碼編排原則
  (一),文字之選擇及字體悉依教育部[漢字標準字體表]爲基準。說明:中 國文字的困擾主要有兩方面,一是文字的數量太大,二是異體字繁多。實際上一般人常用的不過七千字左右,新字又不斷的增加,造成中文資料處理上的困難;而教 育部的標準字體表之字集系經多年之蒐集、考證、分析、選取,爲較不偏頗,最具客觀性之用字字集,應能符合一般使用者之需求。
  (二),以2個字節(bytes)爲中文碼編碼單位,並以十六進位制之文數字表示之。說明:[以2個字節爲字碼單位,於處理時可增加信息傳輸之速度],符合一般資料處理作業之需要。採用十六進位制數字編碼,系因應資料處理人員慣用之進位法,用以表示兩字節最爲簡明。
   (三)符合CNS5205及CNS7654之通信定則。說明:本編碼爲符合CNS5305及CNS7654通信定則之規定,所有控制碼均予避開,即字碼 中之00至20以及7F均予避開,則7BIT字碼集共有94個編碼位置,兩個字節革命可編8836箇中文字碼,訂爲一字面。
  (四),依字之使用頻率而編排於各不同字面。說明:在做信息傳輸時,若欲傳送出現在不同字面上的字,必須先送出轉字面控制碼。爲提高傳輸效率,常會一起出現的字編在同一字面中,可減低字面轉換的次數。
  (五),使先筆畫後部首的排列順序來編訂字碼。說明:每一字面均按文字滅口筆畫數爲首序編訂字碼,使用者以筆畫數即可查尋字碼。
  六、字集之說明
  第一字面:本編碼系統爲減少字面轉換次數,特編最常用之中文字及符號、字母、部首等於第一字面;所編字彙及碼區分別說明如下:
  1,符號區
  符號區之編碼位置規劃於第一字面之2121至427E,有3102個編碼位置,目前暫編符號684個,所餘空位供爾後增添之用。
  已編入之特殊符號及文字類別如下:
  (1),間隔符號1個。
  (2),標點符號28個。
  (3)括號及製表符號89個。
  (4),一般符號34個。
  (5)、學術符號51個。
  (6)、單位符號31個。
  (7)數字符號42個,包括阿拉伯數字10個,羅馬數字大小寫共20個,中國數字12個。
  (8)外文字母100個,包括大寫英文字母,小字英文字母各26個,大寫希臘字母、小寫希臘字母各24個。
  (9)漢字注音符號42個。

  (10)數字序列符號20個。
  (11)中國文字部首213個(夕,夕兩部首同歸於夕部首中,夕部首得於將來擴編時一併列入增訂。)
  (12)控制碼符號33個。
  2 中文字區
   CNS第一字面之中文字區編碼區間由4421至7D4B,所編字彙5401字,除包括教育部頒訂之“常用漢字標準字體表”所列全部4808字外,並優收 編國中、國小教科書中常用字587字及異體字6字。第二字面:本字集所編字彙7650字,除教育部所頒“次常用漢字標準字體表”外,並篩選編入罕用字表中 使用頻率較高之1320字。字碼區間爲2121至7244。第三字面:本字集即77年6月行政院主計處電子處理資料中心爲蒐集仍涵蓋教育部罕用及異體字表 中之較常用字,所編訂之使用者加字區第14字面字集第一部分,字數6148字;原碼序不變,字碼區間仍爲2121至6246。第四字面:本字集所編字彙 7298字,除包括原第14字面第二部分171字外,並蒐集戶役政及其他使用單位,ISO10646第2版漢字集、信息業次常用字而成,字碼區間爲 2121至6E5C。第五字面:本字集所編字彙共8603個字,系未包含於前4個字面之教育部罕用字。字碼區間爲2121至7C51。第六字面:本字集所 編字彙共6388個字,爲不包含於前5個字面且筆畫在14畫(含)以下之教育部異體字。字碼區間爲2121至647A。第七字面:本字集所編字彙6539 個字,爲不包含前6個字面之教育部異體字,字碼區間爲2121爲6655。使用者得視自己的需求參考本標準之字集、字序編訂內碼錶。
  七,CNS11643之使用
   (一)字面之指定與轉換依據CNS7654(78年7月15日版)第5。3。9節之規定,中文碼可置於多字節符號字庫(MULTIPLE BYTE GRAPHIC  REPERTOIRE)中,經由ESC2/4 2/9 F四個字節之逸出順序碼指定於G1字集,或經由ESC2/4 2/10 F指定於G2字集,亦可經由ESC2/4 2/11 F指定於G3字集,其中F 可用3/0~3/15來指定相對之一至十六中文字面;至於英文之字集則可經由ESC2/8 F 指定於G0字面。在7個位元的環境下,對於各種字面的使用說明如下:1,利用SI使用G0字面,併爲鎖定方式。       2,利用SO使用G1字面,併爲鎖定方式。3,利用LS2使用G2字面,併爲鎖定方式。4,利用LS3使用G3字面,併爲鎖定方式。5,利用SS2使用 G2字面,併爲非鎖定方式。6,利用       SS3使用G3字面,併爲非鎖定方式。
  爲求使用方便,終端設備在開機時可將G0、G1、G2等三個字集分別設定爲ASCII、第一字面及第二字面,將G3字集設定爲其他較常用的字面。有關這些控制碼的使用,請參考CNS7654        。
  (二)使用者加字區之使用:
  爲適應各種不同性質之中文資料處理作業,CNS11643特別訂定自第十二字面起爲使用者加字區;尚未收編於本系統之中文字或符號。由使用者視需要先編於此區內使用;字面之指定與轉換方法與前七個字面相同。
  八,CNS11643之推廣應用
   本交換碼系統依國家標準法之規定,系由經濟部中央標準局負責檢討增修之,但該局爲加強推廣該標準之應用,特將此係統及中文字型檔委託本中心代爲辦理推廣 應用事宜;本中心爲顧及標準字型檔之完整性,以利此標準之推廣,另再商得內政部及經濟部工業局同意一併提供其他字型檔。
  CNS11643目前之應用情形如下:
  (一)臺灣之應用情形
  1,公文電子交換之標準傳遞碼,行政院“政府機關公文電子傳遞作業”決定,凡是經“交換中心”(交通部管資中心)之公文,一律須先轉換爲CNS後再傳遞。
  2,EUC碼援用CNS之字集及架構:UNIX系統上使用之EUC雖爲4BYTE之內碼,但卻全部採用CNS之編碼架構及字集;其2個低字節之HIGH均OFF後字碼即與CNS完全相同,因此不需再以對照表方式轉換;亦可視爲CNS應用於內碼之實例。
  3,BIG5+碼之字源:86年7月完成之“BIG5+”(即BIG-5碼之擴編)系以CNS11643爲藍本,納編CNS第3字面之4,145個、第4字面之219個一般文書常用之中文字。
  (二)國外之應用情形
   ISO10646及UNICODE漢字均收編CNS字集:ISO10646及UNICODE目前共收編20902個漢字,其中17011個字系來自 CNS(第1第2字面及第3字面3895個,第4字面56個),現又增編CNS的5881個字。因此,不便臺灣標準得與國際標準相容,國內電腦業者在國際 市場之競爭力得以增強,將來ISO10646及UNICODE發展成熟後,使用者亦可得以順利轉換。
  七,CCCII編碼
   CCCII編碼是CHINESECHARACTER CODE FOR INformATION INTERCHANGE 的縮寫,是經臺灣中研院中美會及國科會等單位支持,於1979年12月25日集合由臺灣圖書館學者,文字學家及電腦專家組成“漢字整理小組”提出的漢字編 碼,已廣泛用於港臺圖書館及與美國網上數字化圖書信息中心OCLC系統。該編寫系統提供了94面(PLANE)×行(ROW)×94列 (CELL)=830584字符空間;其中每六個面構成一個層(LAYER)提供6×94×94=53016編碼空間,(最後一層只有四個面)。各層定義 的漢字情況如下:
  第1層,符號和繁體漢字。
  第2層,大陸的簡體漢字。
  第3-12層,漢字異體字。
  第13層,日本漢字。
  第14層,朝鮮漢字。
  第15層,保留字。
  第16層,雜項字(日本與朝鮮)
  第一至十二層的編碼的編碼存在關聯含義,就是說同樣的碼在這些不同的層表示同一個漢字的不同變形。如第一層表示繁體字,第二層表示大陸簡體字(如果有的話),第三至十二層表示其他的異體字,例如以下這個字的三種變形,編碼的第二三字節是相同的:
  字形類型編碼點,層字樣
  繁體字  OX224E411
  簡體字  OX284E412
  異體字  OX2E4E413
   第一層所定義的字符集如下:第1面/第2行56數學符號第1面/第3行ASCII第1面/第11行35中文標點符號第1面/第12-14行214康熙字 典偏旁部首第1面/第15行41中文數字,37拼音符號,4音調符號第1面/第16-67行4808備用字,字碼213021-21637E第1面/第 68行-第3面/第64行17032備用字,字碼216421-23607E20583罕用字,字碼爲236121-262543第3面/第65行含教育 部頒定之罕用字彙12924字,次常用字彙314字,第6面/第5行以及康煕字典、中文大辭典、財稅資料考覈中心字彙、電信傳輸碼字彙、五大專題碼字彙, 與其他信息字彙7345字。
  第二層收異體字共11517字,其中包含大陸簡體字3625字,其它簡體字7892字所有各層的第一行均爲保留行,共收字53940個。
   四交大資料-BBS95年1月中國文字資料庫(CCDB)字型集的應用(1)中國文字資料庫(CCDB)字型集的應用(2)中國文字資料庫(CCDB) 字型集的應用(3)中國文字資料庫(CCDB)屬性檔介紹。三,ANSIZ39.64-1989 THIS NATIONALSTANDARD IS DESIGNATED as ANSIZ39.64-1989 and named “EAST ASIAN CHARACTER CODE”(EACC),but wasorigianlly known as REACC (RLIN EAST ASIAN CHARACTER CODE), THAT IS BEFORE ITBECAME A NATIONAL STANDARD RLIN STANDS FOR “RESEARCH LIBRARIES INformATIONNETWORK “ which was developed by the
 B ,瀏覽器:IE4。01(或更高的版本)中文版,或NETSGAPENAVIGATOR 3。X
 2,其他語種的WINDOWSS 95(或更高的版本)+微軟簡體中文支持或外掛中文平臺。一般情況下,使用外掛中文平臺時,需要將當前環境設置成爲GBK碼,並關閉漢字自動識別的功能。而且,許多外掛中文平臺不支持全部GBK漢字。
 3,已知的常見錯誤。
 A,IE4。0無法顯示GBK/4 AB-AF、F9-FD以及FE 中 FE40-FE4F各位置的漢字。
 B,在簡體WINDOWS95環境下,NETSGAPE NAVIGATOR4。X 無法顯示GBK/3中XXA0位置的漢字,A040-AOFE位置顯示錯誤。
 C,在繁體WINDOWS95環境下,NETSGAPE NAVIGATOR4。X不能正確顯示GBK/3-GBK/5之間的字符。
 GBK代表碼(按分類順序排列)
 GBK/1:GB2312非漢字符號A1-A9
 B0-B7B8-BF C0-C7C8-CF D0-D7
 GBK/2:GB2312漢字
 D8-DFE0-E7E8-EFF0-F7
 81-8384-87 88-8B8C-8F 90-93
 GBK/3:擴充漢字
 94-9798-9B 9C-A0
 AA-AFB0-B7B8-BFC0-C7C8-CF
 GBK/4:擴充漢字
 D0-D7D8-DFE0-E7E8-EFF0-F7
 F8-FE
 GBK/5:擴充非漢字
 A8-A9
 (1)AA-AF  (2)F8-FE
 用戶自定義區
 (3)A1-A7

 --------------------------------------------------------------------------------
  九、ISO10646及UNICODE
  一,字碼架構
  ISO10646 及UNICODE均爲多漢字文內碼系統
  ISO10646之漢字碼長度:4 BYTE
  UNICODE 之漢字碼長度:2 BYTE
  新版UNICODE 之漢字碼長度:2-4 BYTE
  二,與CNS11643之關係字集相容但字序不同
  ISO10646及UNICODE之漢字集目前共收編20901個漢字,其中17011個系來自CNS字集(包括第1第2字面字集全部及第3字面字集3895字,第4字面字集56字),現已增編CNS的5881個字。
  UNICODE即所謂的“統一碼”,在16位的範圍內,將世界各國的文字都放在同一平面上,這樣就不會出現某一位置在這種語中是這個字,在那種語言版本中是另一個字。
  11,GB13000。1收入的31個IBM OS/2專用符號。
  二,碼位亦採用雙字節表示,總體編碼範圍爲8140-FEFE,首字節在81-FE之間,尾字節在40-FE之間,剔除XX7F一條線。總計23940個碼位,共收入21886個漢字和圖形符號,其中漢字(包括部首和構件)21003個,圖形符號883個。
  全部編碼分爲三大部分:
  三,字形
  GBK對字形作爲如下規定
  1,原則上與GB13001。1G列(即源自中國大陸法定標準的漢字)下的字形/筆畫保持一致。
  2,在CJK漢字認同規則的總框架內,對所有的GBK編碼漢字實施“無重正形”(“GB化”);即在不造成重碼的前提下,儘量採用中國新字形。
  3,對於超出CJK漢字認同規則的,或認同規則尚未明確規定的漢字,在GBK碼位上暫安放舊字形。這樣,在許多情況下,GBK收入了同一漢字的新舊兩種字形。
  4,非漢字符號的字形,凡GB2312已經包括的,與GB2312保持一致,超出GB2312的部分,與GB13000。保持一致。
  5,帶聲調的拼音字母取半角形式。
  四,目前應用
   在基本事件環境方面,微軟公司自WINDOWS95簡體中文版始,系統採用GBK代碼,它包括了TRUETYPE宋體、黑體兩種GBK字庫(北京中易電 子公司提供),可以用於顯示和打印,並提供了四種GBK漢字輸入法。此外,瀏覽器IE4。0簡體,繁體中文版內提供了一個GBK-BIG5代碼雙向轉換的 功能。
  微軟公司爲INTERNET EXPLORER 提供的語言包中,簡體中文支持(SIMPLIFIED CHINESE LANGUAGE SUPORT KIT)的兩種字庫宋體、黑體,也是GBK漢字(珠海四通電腦排版系統開發公司提供),其他一些中文字庫生產廠商,也開始提供TRUE TYPE 或 POSTSCRIPT GBK字庫。
  許多外掛式的中文平臺,如南極星、四通利方(RICHWIN)等,提供GBK碼的支持,包括字庫、輸入法和GBK與其他中文代碼的轉換器。
  在互聯網方面,許多網站的網頁使用了GBK代碼,如《人民日報》等。
   但是,多數搜索引擎,都不能很好的支持GBK漢字的搜索。大陸地區的搜索引擎,有些能夠不完善地支持GBK漢字檢索,比如,檢索GBK漢字“鎔”,只有 在網易等極個別的兩三個搜索引擎中查能,而檢索“朱鎔基”三個字,則能在搜索客(CSEEK)、天網等更多的幾個搜索引擎中查到。而港臺和國外的搜索引 擎,基至是知名的,具有簡體中文查詢能力的搜索引擎,如YAHOO!、OPENFIND、 ALTAVISTA等,都不支持GBK搜索。
  其他應用方面,微軟公司的OFFICE 95簡體中文版以上版本,提供GBK碼的檢索和排序。(按筆畫和拼音兩種方式)
  五,顯示GBK碼錶的要求
  1,在滿足下列環境要求時,才能保證全部字符顯示準確,否則可能會出現缺字、顯示錯誤或亂碼。
  A ,基礎環境,WINDOW9X簡體中文版,或WINDOWS95繁體中文版(或更高的版本)+微軟簡體中文支持。
 

另一個

一、漢字編碼的種類

    漢字編碼中現在主要用到的有三類,包括GBK,GB2312和Big5。

    1、 GB2312又稱國標碼,由國家標準總局發佈,1981年5月1日實施,通行於大陸。新加坡等地也使用此編碼。它是一個簡化字的編碼規範,當然也包括其他 的符號、字母、日文假名等,共7445個圖形字符,其中漢字佔6763個。我們平時說6768個漢字,實際上裏邊有5個編碼爲空白,所以總共有6763個 漢字。

       GB2312規定“對任意一個圖形字符都採用兩個字節表示,每個字節均採用七位編碼表示”,習慣上稱第一個字節爲 “高字節”,第二個字節爲“低字節”。GB2312中漢字的編碼範圍爲,第一字節0xB0-0xF7(對應十進制爲176-247),第二個字節 0xA0-0xFE(對應十進制爲160-254)。

       GB2312將代碼表分爲94個區,對應第一字節 (0xa1-0xfe);每個區94個位(0xa1-0xfe),對應第二字節,兩個字節的值分別爲區號值和位號值加32(2OH),因此也稱爲區位碼。 01-09區爲符號、數字區,16-87區爲漢字區(0xb0-0xf7),10-15區、88-94區是有待進一步標準化的空白區。

    2、 Big5又稱大五碼,主要爲香港與臺灣使用,即是一個繁體字編碼。每個漢字由兩個字節構成,第一個字節的範圍從0X81-0XFE(即129-255), 共126種。第二個字節的範圍不連續,分別爲0X40-0X7E(即64-126),0XA1-0XFE(即161-254),共157種。

    3、 GBK是GB2312的擴展,是向上兼容的,因此GB2312中的漢字的編碼與GBK中漢字的相同。另外,GBK中還包含繁體字的編碼,它與Big5編碼 之間的關係我還沒有弄明白,?孟袷遣灰恢碌摹?GBK中每個漢字仍然包含兩個字節,第一個字節的範圍是0x81-0xFE(即129-254),第二個字 節的範圍是0x40-0xFE(即64-254)。GBK中有碼位23940個,包含漢字21003 個。                          

                                   表1 漢字編碼範圍

                    名稱    第一字節              第二字節
 
                    GB2312  0xB0-0xF7(176-247)    0xA0-0xFE(160-254)
 
                    GBK     0x81-0xFE(129-254)    0x40-0xFE(64-254)
 
                    Big5    0x81-0xFE(129-255)    0x40-0x7E(64-126)

                                                  0xA1-0xFE(161-254)
 

 

二、對漢字進行hash

    爲了處理漢字的方便,在查找漢字的時候,我們通常會用到hash的方法,那怎麼來確定一個漢字位置呢?這就和每種編碼的排列有關了,這裏主要給出一種hash函數的策略。

    對於GB2312編碼,設輸入的漢字爲GBword,我們可以採用公式(C1-176)*94 + (C2-161)確定GBindex。其中,C1表示第一字節,C2表示第二字節。具體如下:

    GBindex = ((unsigned char)GBword.at(0)-176)*94 + (unsigned char)GBword.at(1) - 161;

    之所以用unsigned char類型,是因爲char是一個字節.

    對於GBK編碼,設輸入的漢字爲GBKword,則可以採用公式   index=(ch1-0x81)*190+(ch2-0x40)-(ch2/128),其中ch1是第一字節,ch2是第二字節。

    具體的,

    GBKindex = ((unsigned char)GBKword[0] - 129) * 190 + ((unsigned char)GBKword[1] - 64) - (unsigned char)GBKword[1] / 128;

三、怎樣判斷一個漢字的是什麼編碼

    1、判斷是否是GB2312

    bool isGBCode(const string& strIn)

    {

        unsigned char ch1;

        unsigned char ch2;

        if (strIn.size() >= 2)
        {

            ch1 = (unsigned char)strIn.at(0);

            ch2 = (unsigned char)strIn.at(1);

            if (ch1>=176 && ch1<=247 && ch2>=160 && ch2<=254)

                return true;

            else return false;
        }

        else return false;

    }

    2、判斷是否是GBK編碼

    bool isGBKCode(const string& strIn)

    {

        unsigned char ch1;

        unsigned char ch2;

        if (strIn.size() >= 2)

        {

            ch1 = (unsigned char)strIn.at(0);

            ch2 = (unsigned char)strIn.at(1);

            if (ch1>=129 && ch1<=254 && ch2>=64 && ch2<=254)

                return true;

            else return false;

        }

        else return false;

    }

    3、對於Big5

        它 的範圍爲:高字節從0xA0到0xFE,低字節從0x40到0x7E,和0xA1到0xFE兩部分。判斷一個漢字是否是BIG5編碼,可以如上對字符的編 碼範圍判斷即可。如何定位呢?那麼也想象所有編碼排列爲一個二維座標,縱座標是高字節,橫座標是低字節。這樣一行上的漢字個數:(0x7E- 0x40+1)+(0xFE-0xA1+1)=157。那麼定位算法分兩塊,爲:  

        if 0x40<=ch2<=0x7E: #is big5 char 

        index=((ch1-0xA1)*157+(ch2-0x40))*2 

        elif 0xA1<=ch2<=0xFE: #is big5 char 

        index=((ch1-0xA1)*157+(ch2-0xA1+63))*2 

四、如果判斷一個字符是西文字符還是中文字符

    大家知道西文字符主要是指ASCII碼,它用一個字節表示。且這個字符轉換成數字之後,該數字是大於0的,而漢字是兩個字節的,第一個字節的轉化爲數字之後應該是小於0的,因此可以根據每個字節轉化爲數字之後是否小於0,判斷它是否是漢字。

    例如,設輸入字爲strin,則,

    If (strin.at(0) < 0)

        cout << "是漢字" << endl;

     else

        cout << "不是漢字" << endl;

     補充:

     1.漢字外部碼

     漢字外部碼又稱爲漢字輸入碼,是指從鍵盤上輸入漢字時採用的編碼。漢字輸入編碼有很多種,目前廣泛使用的輸入碼爲:

     ① 國標區位碼

     ② 以漢字讀音爲基礎的拼音碼,如全拼輸入法、雙拼輸入法、詞彙輸入法、智能ABC輸入法等;

     ③ 以漢字字形爲基礎的拼形碼,如五筆字型輸入法;

     不同的漢字輸入方法有不同的外碼,但內碼只能有一個。好的輸入方法應具備規則簡單、操作方便、容易記憶、重碼率低、速度快等特點。

     2.漢字國標碼

     GB2312-80編碼簡稱國標碼。由於漢字數量大,無法用一個字節進行編碼,因此使用兩個字節對漢字進行編碼。規定兩個字節的最高位用來區分ASCII碼。這樣國標碼用兩個字節的低7位對漢字進行編碼。

     一 個字節只能有128-34=94種狀態用於漢字編碼(34是指34種控制字符),兩個字節可以表示94×94=8836種狀態。在基本集中漢字是按規則排 列成94行和94列的矩陣,形成漢字編碼表,其行號稱爲區號,列號稱爲位號,第一個字節表示漢字在國標字符集中的區號,第二個字節表示漢字在國標字符集中 的位號。每一個漢字在94×94的矩陣中都有一個固定的區號和位號。

     例如:漢字“大”的區號爲20,位號爲83,即“大”的區位碼爲2083。

     國標碼是以十六進制數字編碼,編碼範圍是從2121H(21H即爲十進制的33)到7F7FH(7FH即爲十進制的127)。

     因此,國標碼=區位碼(用十六進制表示)+2020H。

     3.漢字機內碼

     機內碼是指一個漢字被計算機內部系統進行存儲、處理和傳輸時而使用的編碼。爲了保證中西文兼容,同時又能區分ASCII碼和漢字,因此,機內碼就是將國標碼的兩個字節的最高位置爲“1”。

     所以,機內碼=國標碼+8080H=區位碼(用十六進制表示)+A0A0H 。

     4.漢字字形碼

     字形碼又稱漢字字模,用於漢字的輸出。漢字的字形通常採用點陣的方式產生。漢字點陣有16×16點陣、32×32點陣、64×64點陣,點陣不同,漢字字形碼的長度也不同。點陣數越大,字形質量越高,字形碼佔用的字節數越多。

     如圖1.1是“國”字24×24的點陣字形。深色小正方形可以表示一個二進制位的信息“1”,淺色小正方形表示二進制位的信息“0”。

     漢字字形碼又稱爲漢字輸出碼或漢字發生器的編碼。

     例:按32×32點陣存放兩級漢字的漢字庫,大約需要佔用多少字節?

     解:32×32×6763÷8=865664B≈845KB

     大約需要845KB。

 

 


發佈了53 篇原創文章 · 獲贊 21 · 訪問量 37萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章