首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

BIG5 轉 GB 碼表轉換技術實作:從編碼原理到完整 C 程式碼

     編輯:關於C++

繁簡中文編碼不相容是跨地區軟體開發常見痛點。大陸採用 GB 碼 (GB2312/GBK),台灣採用 BIG5 碼,雙方編碼對應關係非線性,必須透過碼表查表轉換。本文完整記錄從碼表製作到雙向轉換程式的實作細節。

BIG5 編碼結構分析

  • 雙位元組編碼:第一位元組 0x81–0xFE (126 個),第二位元組 0x40–0x7E + 0xA1–0xFE (157 個)
  • 理論容量:126 × 157 = 19,782 字元
  • 常用字區:0xA440–0xC671 (5,401 字)
  • 次常用字區:0xC940–0xF9FE (7,652 字)
  • 其餘為特殊符號

步驟一:製作 BIG5→GB 碼表檔

  1. 窮舉所有合法 BIG5 編碼 (0xA100–0xFEFF) 寫入二進位檔 Table.txt
  2. 使用支援 BIG5→GB 轉換的工具 (地球村、東方快車、四通利方) 將 Table.txt 轉為 GB 碼
  3. 產出的檔案即為碼表:位置索引 = BIG5 編碼,內容 = 對應 GB 碼

// Table.txt 產生程式 (Turbo C++ 3.0)
#include 
#include 
void main() {
    FILE *fp = fopen("table.txt", "wb");
    for (int hi = 0xA1; hi <= 0xFE; hi++)
        for (int lo = 0x00; lo <= 0xFF; lo++) {
            fwrite(&hi, 1, 1, fp);
            fwrite(&lo, 1, 1, fp);
        }
    fclose(fp);
}

步驟二:BIG5 檔案轉 GB 碼核心演算法

關鍵邏輯:將 BIG5 雙位元組映射為碼表線性索引:


if (hi >= 0xA1 && hi <= 0xFE) {  // 判斷為漢字首位元組
    if (lo >= 0x40 && lo <= 0x7E)  // 第二區間
        lo = lo - 0x40;
    else if (lo >= 0xA1 && lo <= 0xFE)  // 第三區間
        lo = lo - 0xA1 + 0x7E - 0x40 + 1;
    
    // 線性索引計算
    index = (hi - 0xA1) * (0xFE - 0xA1 + 1 + 0x7E - 0x40 + 1) + lo;
    // 碼表每項 2 位元組 (GB 碼雙位元組)
    fseek(table, 2 * index, SEEK_SET);
    fread(&gb_hi, 1, 1, table);
    fread(&gb_lo, 1, 1, table);
    fwrite(&gb_hi, 1, 1, dest);
    fwrite(&gb_lo, 1, 1, dest);
} else {
    fwrite(&hi, 1, 1, dest);  // ASCII 直通
}

完整轉換程式 (Turbo C++ 3.0)


#include 
#include 
void main() {
    int hi, lo;
    FILE *src = fopen("big.txt", "rb");
    FILE *tab = fopen("table.txt", "rb");
    FILE *dst = fopen("gb.txt", "wb");
    
    while (!feof(src)) {
        fread(&hi, 1, 1, src);
        if (feof(src)) break;
        if (hi >= 0xA1 && hi <= 0xFE) {
            fread(&lo, 1, 1, src);
            if (lo >= 0x40 && lo <= 0x7E) lo = lo - 0x40;
            else if (lo >= 0xA1 && lo <= 0xFE) lo = lo - 0xA1 + 0x7E - 0x40 + 1;
            fseek(tab, 2 * ((hi - 0xA1) * 157 + lo), SEEK_SET);
            fread(&hi, 1, 1, tab);
            fread(&lo, 1, 1, tab);
            fwrite(&hi, 1, 1, dst);
            fwrite(&lo, 1, 1, dst);
        } else {
            fwrite(&hi, 1, 1, dst);
        }
    }
    fclose(src); fclose(tab); fclose(dst);
}

移植與擴展建議

  • 編譯器適配:BCB/VC/VB 中需調整檔案 I/O API (如 CFile、fstream、OpenFile)
  • 雙向轉換:同理製作 GB→BIG5 碼表,邏輯對稱
  • 效能優化:碼表載入記憶體陣列 (unsigned char table[45840]) 避免頻繁 fseek
  • 編碼擴展:GBK/GB18030、BIG5-HKSCS、UTF-8 互轉建議使用 ICU、iconv 等成熟庫

雖然現代開發多採用 Unicode (UTF-8/UTF-16) 內碼統一避免轉換,但理解雙位元組編碼映射原理、碼表查表機制,對維護舊系統、處理歷史資料、嵌入式資源受限環境仍具實務價值。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved