GB碼與BIG5是中國人常用的兩種編碼集。GB碼為大陸使用,BIG5為香港與台灣使用。每個編碼都由2個字符構成,高字節在前,低字節在後。下面我將使用Python實現的編碼轉換的程序向大家作一個介紹。關於編碼的一些知識大家可以去網上查找,本人不再贅述。 GB碼是大陸使用的編碼集。以前使用的為GB-2312編程,它只有常用字,字數有限。後國家制定了新的GBK編碼,漢字已經達到了2萬多。GBK完全兼容原GB-2312編碼,也就是説一個GB2312的編碼在GBK上是一模一樣的。這裏所介紹的轉換是以GBK為基礎的,因此適用性很廣。GBK編碼中不僅包括了原GB-2312編碼,同時也包括了許多簡碼的繁體碼,同時還有許多的符號與不常用漢字。GBK編碼的範圍是:高字節從0x81到0xFE,低字節從0x40到0xFE,同時不包括0x7F。這樣如果我們將其排成一個矩形,看上去就少了xx7F一根線。

編碼的定位
那麼如何定位一個GBK碼呢?當我們拿到一個編碼時,如何判斷是不是一個GBK碼,如果是GBK碼如何定位它的位置呢?

判斷一個GBK碼應該比較簡單,我們只要根據它的有效範圍進行判定即可。如:

if 0x81<=ch1<=0xFE and (0x40<=ch2<=0x7E or 0x7E<=ch2<=0xFE): #is gb char

這裏ch1和ch2分別是一個字符的高字節和低字節。

如何定位(為什麼要定位我們在後面講)?首先介紹一下碼錶。碼錶是所有編碼放在一起形成的,你可以將其放在文件中(這裏講述的是將編碼放在文件中)。我們在存放編碼時是將有實際意義的編碼放在了一起(因為有一些組合是不存在的),而且是按字節大小的順序放的。根據GBK的編碼範圍,我們可以設想一個二維座標,縱座標是高字節,橫座標是低字節,每一個交叉點上是一個漢字,佔兩個字節。這樣一行上的漢字個數應該為0xFE-0x40+1-1=190(加1是因為要把0x40也算進去。減1是因為要把7F去掉)。定位時,我們先用高字節減去0x81,得到縱座標偏移量。用低字節減去0x40得到橫座標偏移量。用縱座標偏移量乘以每個漢字個數,加上橫座標偏移量就得到漢字的偏移量。再乘以2得到字節的偏移量。那麼定位算法為:

index=((ch1-0x81)*190+(ch2-0x40)-(ch2/128))*2

上面的算法中有-(ch2/128)。這是因為GBK中沒有7F碼,因此當ch2小於7F時,ch2/128=0,則表示7F沒有計算在內。而當ch2大於7F時,ch2/128=1,則表示多算了7F一值,因此要去掉。由於一個漢字有兩個字節,故要乘以2。這樣我們就得到一個GBK漢字在碼錶中的字節位置了。

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。

編碼轉換
上面,我們已經可以得到GBK漢字和BIG5的字節位置。那麼就可以開始進行轉換了。對於轉換我原以為有一個特別的算法,能夠按照兩種編碼的不同,簡單地通過計算就可以得出結果來,其實是不存在這種算法的。真正的做法是通過建立轉換碼錶文件實現的。即對於GBK碼錶,將原位置上的GBK漢字改成相應的BIG5漢字。對於BIG5碼錶,將原位置上的BIG5漢字改成相應的GBK漢字。這樣,由於原來漢字的位置沒有變,但編碼已經變成了想要轉換的編碼。通過計算出原漢字的位置,將轉換碼錶中對應漢字位置的字符取出來,這樣就完成了轉換(這就是為什麼要進行編碼定位的原因)。的確,程序是簡單的,但真正細緻的工作是在建立轉換碼錶上。我們需要從GBK轉BIG5的碼錶文件,和BIG5轉GBK的碼錶文件。好在這一工作已經有人完成了,在網上可以找到這種信息。本人就是在網上找到了這種對應的轉換碼錶,於是完成了一個用Python做的編碼轉換程序。