汉字编码转换原理及方法
一、基本概念
· GB碼
全稱是GB2312-80《信息交換用漢字編碼字符集?基本集》,1980年發布,是中文信息處理的國家標準,在大陸及海外使用簡體中文的地區(如新加坡等)是強制使用的唯一中文編碼。P-Windows3.2和蘋果OS就是以GB2312為基本漢字編碼,?Windows 95/98則以GBK為基本漢字編碼、但兼容支持GB2312。GB碼共收錄6763個簡體漢字、682個符號,其中漢字部分:一級字3755,以拼音排序,二級字3008,以偏旁排序。該標準的制定和應用為規范、推動中文信息化進程起了很大作用。1990年又制定了繁體字的編碼標準GB12345-90《信息交換用漢字編碼字符集?第一輔助集》,目的在于規范必須使用繁體字的各種場合,以及古籍整理等。該標準共收錄6866個漢字(比GB2312多103個字,其它廠商的字庫大多不包括這些字),純繁體的字大概有2200余個。(2312集與12345集不是相交的。一個是簡體,一個是繁體)
· BIG5編
是目前臺灣、香港地區普遍使用的一種繁體漢字的編碼標準,包括440個符號,一級漢字5401個、二級漢字7652個,共計13060個漢字。Big-5?是一個雙字節編碼方案,其第一字節的值在?16?進制的?A0~FE?之間,第二字節在?40~7E?和?A1~FE之間。因此,其第一字節的最高位是?1,第二字節的最高位則可能是?1,也可能是?0。
· GBK編碼(Chinese Internal Code Specification)
GBK編碼(俗稱大字符集)是中國大陸制訂的、等同于UCS的新的中文編碼擴展國家標準。GBK工作小組于1995年10月,同年12月完成GBK規范。該編碼標準兼容GB2312,共收錄漢字21003個、符號883個,并提供1894個造字碼位,簡、繁體字融于一庫。Windows95/98簡體中文版的字庫表層編碼就采用的是GBK,通過GBK與UCS之間一一對應的碼表與底層字庫聯系。其第一字節的值在?16?進制的?81~FE?之間,第二字節在?40~FE,除去xx7F一線。
· Unicode編碼(Universal Multiple Octet Coded Character Set)
國際標準組織于1984年4月成立ISO/IEC JTC1/SC2/WG2工作組,針對各國文字、符號進行統一性編碼。1991年美國跨國公司成立Unicode Consortium,并于1991年10月與WG2達成協議,采用同一編碼字集。目前Unicode是采用16位編碼體系,其字符集內容與ISO10646的BMP(Basic Multilingual Plane)相同。Unicode于1992年6月通過DIS(Draf International Standard),目前版本V2.0于1996公布,內容包含符號6811個,漢字20902個,韓文拼音11172個,造字區6400個,保留20249個,共計65534個。
二、一些注解
在此解釋一下我們常見的一些漢字內碼轉換工具:
1、?最常見的是GB2Big5和Big52GB轉換工具。這里的GB指是GB2312集。
2、?GBK簡體兼容GB2312字符集及其編碼。不規范理解為GB就是GBK簡體。
3、?繁體不等同于Big5,在GBK集中也有繁體,GB12345集也有繁體。但這三者的漢字編碼方式不同。Windows95/98/NT/2000(簡體中)中使用的都是GBK字符集;繁體版使用的是Big5字符集,在簡體版中無法正常顯示Big5字符,繁體版無法顯示GB字符。
4、?在IE中,進入Big5碼網站(如:臺灣網站),如果安裝有Big5字符集支持,IE會將Big5網頁轉換成GBK繁體顯示,沒有則是亂碼。IE以GBK繁體顯示時,在網頁中輸入的漢字應當是GBK繁體,以Big5碼顯示時(亂碼),要輸入Big5碼字符(輸入亂碼?先輸入GBK簡體----GB碼,再使用小工具將其轉換成Big5,拷貝,粘貼即可)。
5、?常見的小工具中,可將Big5轉換成GBK繁體的不多,可將GBK簡體繁體相互轉換的也不多。其原因是,他們是將GB2312字符集與Big5字符集建立了對應關系。
三、內碼轉換原理及方法
內碼轉換:就是在不同字符集之間建立一種對應關系。
以GBK2Big5(簡繁體都可)
如:讓字,在GBK中編碼是C8C3。如果我們將GBK碼表中的字符變成Big5碼格式,則C8C3位上的應該是”?讓”字的Big5碼字符”琵”(琵字不是GBK中的琵,而是”讓”字的Big5碼漢字在GBK環境中顯示結果)。這樣我們讀出要轉換的文字,在GBK(已經轉換成Big5格式)碼表中找到它的位置,取出該位置上的字符,將原字符替換即可。
讀寫字符不是問題。關鍵是如何在碼表文件中對該漢字進行定位和如何將純GBK碼表轉換成Big5格式表示的GBK碼表。
問題一、對漢字進行定位。
GBK?代碼表(按代碼順序排列)?
81-87 88-8F 90-97 98-9F A0-A7 A8-AF B0-B7 B8-BF
C0-C7 C8-CF D0-D7 D8-DF E0-E7 E8-EF F0-F7 F8-FE
81 0 1 2 3 4 5 6 7 8 9 A B C D E F
4?丂?丄?丅?丆?丏?丒?丗?丟?丠?両?丣?並?丩?丮?丯?丱
5?丳?丵?丷?丼?乀?乁?乂?乄?乆?乊?乑?乕?乗?乚?乛?乢
6?乣?乤?乥?乧?乨?乪?乫?乬?乭?乮?乯?乲?乴?乵?乶?乷
7?乸?乹?乺?乻?乼?乽?乿?亀?亁?亂?亃?亄?亅?亇?亊?
8?亐?亖?亗?亙?亜?亝?亞?亣?亪?亯?亰?亱?亴?亶?亷?亸
9?亹?亼?亽?亾?仈?仌?仏?仐?仒?仚?仛?仜?仠?仢?仦?仧
A?仩?仭?仮?仯?仱?仴?仸?仹?仺?仼?仾?伀?伂?伃?伄?伅
B?伆?伇?伈?伋?伌?伒?伓?伔?伕?伖?伜?伝?伡?伣?伨?伩
C?伬?伭?伮?伱?伳?伵?伷?伹?伻?伾?伿?佀?佁?佂?佄?佅
D?佇?佈?佉?佊?佋?佌?佒?佔?佖?佡?佢?佦?佨?佪?佫?佭
E?佮?佱?佲?併?佷?佸?佹?佺?佽?侀?侁?侂?侅?來?侇?侊
F?侌?侎?侐?侒?侓?侕?侖?侘?侙?侚?侜?侞?侟?価?侢?
以上是按代碼順序排列GBK碼表,共126個區,每區190個漢字。漢字位置的計算如下:
posit = (ch1 - 129) * 190 + (ch2 - 64) - (ch2/128);(第n?個漢字)
posit = posit * 2;?(第n個字節)
第一個問題就算搞定。
問題二、將GBK碼表用Big5來表示。
我們可以利用現有的工具,如東方快車3000,將GBK碼表轉換成Big5的格式。但實際中有問題,因為GBK較Big5的漢字要多,那么在GBK中有的字符,而Big5中沒有的字符在轉換中可能被刪除,那上面后碼表定位就不能用了。而且實際上幾乎無法定位。不過我在網上找到了一個以Big5表示的GBK碼表的文本(可能是官方的),字符一個不缺。
這個問題也搞定了。
同樣我們可以進行
Big52GBKT(繁體),Big52GBKS(簡體),GBKS2GBKT,GBKT2GBKS,GBK2BIG5的轉化。這里給出Big5碼表格式,和定位算法:
BIG-5?代碼表?
A0-A7 A8-AF B0-B7 B8-BF C0-C7 C8-CF
D0-D7 D8-DF E0-E7 E8-EF F0-F7 F8-FE
(已被轉化成GBK)
B0?0?1?2?3?4?5?6?7?8?9?A?B?C?D?E?F
4?虔?蚊?蚪?蚓?蚤?蚩?蚌?蚣?蚜?衰?衷?袁?袂?衽?衹?記
5?訐?討?訌?訕?訊?託?訓?訖?訏?訑?豈?豺?豹?財?貢?起
6?躬?軒?軔?軏?辱?送?逆?迷?退?迺?迴?逃?追?逅?迸?邕
7?郡?郝?郢?酒?配?酌?釘?針?釗?釜?釙?閃?院?陣?陡?
A? ?陛?陝?除?陘?陞?隻?飢?馬?骨?高?鬥?鬲?鬼?乾?偺
B?偽?停?假?偃?偌?做?偉?健?偶?偎?偕?偵?側?偷?偏?倏
C?偯?偭?兜?冕?凰?剪?副?勒?務?勘?動?匐?匏?匙?匿?區
D?匾?參?曼?商?啪?啦?啄?啞?啡?啃?啊?唱?啖?問?啕?唯
E?啤?唸?售?啜?唬?啣?唳?啁?啗?圈?國?圉?域?堅?堊?堆
F?埠?埤?基?堂?堵?執?培?夠?奢?娶?婁?婉?婦?婪?婀?
定位方法:
if ((ch2 >= 64)&&(ch2 <= 126))
{
posit = (ch1 - 160) * 157 + (ch2 - 64);
posit = posit * 2 - 1;
}
else if ((ch2 >= 161)&&(ch2 <= 254))
{
posit = (ch1 - 160) * 157 + 62 + (ch2 - 160);
posit = posit * 2 - 1;
}
在這里給出GBK2Big5的C++Builder的程序:
fGBK2Big5 = fopen("pureGBK2Big5byOrder.txt", "rb");
unsigned long i,posit;//把gb碼轉換為gbkT
unsigned char ch1,ch2;
String sContext;
char chr;
sContext = Memo1->Lines->Text;
i=1;
while(i < sContext.Length())
{
ch1 = sContext[i];
ch2 = sContext[i+1];
if ((ch1 >= 129)&&(ch1 <= 254))
{
if (((ch2 >= 64)&&(ch2 < 127)) ||((ch2 > 127)&&(ch2 <= 254)))
{
posit = (ch1 - 129) * 190 + (ch2 - 64) - (ch2/128);
posit = posit * 2;
if ((posit > 23940*2) || (posit < 0))
{
i++;
continue;
}
fseek(fGBK2Big5, posit - ftell(fGBK2Big5), 1);
fread((void *)(&chr), sizeof(char), 1, fGBK2Big5);
sContext[i] = chr;
fread((void *)(&chr), sizeof(char), 1, fGBK2Big5);
sContext[i+1] = chr;
i +=2;
}
else
{
i++;
}
}
else
{
i++;
}
}
Memo1->Lines->Text=sContext;
以上很多資料來源于網路燈塔的參考資料(http://www.haiyan.com/steelk/navigator/ref/gbindex1.htm)。
轉載于:https://www.cnblogs.com/bulemaple/articles/2831005.html
總結
以上是生活随笔為你收集整理的汉字编码转换原理及方法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数次冲击IPO无果,是什么阻碍了紫林醋业
- 下一篇: 读《同步脑电-功能磁共振(EEG-fMR