漢字編碼轉換原理及方法
阿新 • • 發佈:2018-11-05
一、基本概念
· GB碼
全稱是GB2312-80《資訊交換用漢字編碼字符集 基本集》,1980年釋出,是中文資訊處理的國家標準,在大陸及海外使用簡體中文的地區(如新加坡等)是強制使用的唯一中文編碼。P-Windows3.2和蘋果OS就是以GB2312為基本漢字編碼, Windows 95/98則以GBK為基本漢字編碼、但相容支援GB2312。GB碼共收錄6763個簡體漢字、682個符號,其中漢字部分:一級字3755,以拼音排序,二級字3008,以偏旁排序。該標準的制定和應用為規範、推動中文資訊化程序起了很大作用。1990年又制定了繁體字的編碼標準GB12345-90《資訊交換用漢字編碼字符集
· 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)
二、一些註解
在此解釋一下我們常見的一些漢字內碼轉換工具:
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)。