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

GB2312 轉 Unicode 轉換表生成器:基於 NIO Charset 實現

     編輯:Java 相關知識

背景

早期中文系統常需在 GB2312/GBK 與 Unicode (UTF-16BE/UTF-8) 之間轉換。JDK java.nio.charset 提供標準化編解碼器,可程序化生成完整對照表,無需手工查表。

核心代碼 (精簡版)

import java.io.*;
import java.nio.*;
import java.nio.charset.*;

public class GB2312UnicodeTableGenerator {

    public static void main(String[] args) throws IOException {
        // GB2312 非標準,JDK 用 GBK 兼容 (超集)
        CharsetDecoder gbDecoder = Charset.forName("GBK").newDecoder();
        CharsetEncoder utf16Encoder = Charset.forName("UTF-16BE").newEncoder();
        CharsetEncoder utf8Encoder = Charset.forName("UTF-8").newEncoder();

        try (OutputStream out = new FileOutputStream("gb2312_unicode.txt")) {
            writeHeader(out);
            int count = 0;

            // GB2312 區位碼:1-94 區,每區 1-94 位
            for (int zone = 1; zone <= 94; zone++) {
                if (isReservedZone(zone)) continue; // 跳過保留區
                writeZoneTitle(out, zone);

                for (int pos = 1; pos <= 94; pos++) {
                    if (!isValidGB(zone, pos)) continue; // 跳過未編碼碼位

                    byte hi = (byte) (0xA0 + zone);
                    byte lo = (byte) (0xA0 + pos);
                    ByteBuffer gbBuf = ByteBuffer.wrap(new byte[]{hi, lo});

                    try {
                        CharBuffer cb = gbDecoder.decode(gbBuf);
                        ByteBuffer utf16Buf = utf16Encoder.encode(cb);
                        cb.rewind();
                        ByteBuffer utf8Buf = utf8Encoder.encode(cb);

                        writeMapping(out, zone, pos, hi, lo, utf16Buf, utf8Buf);
                        count++;
                    } catch (CharacterCodingException e) {
                        // 無效字符跳過
                    }
                    if (pos % 2 == 0) writeNewLine(out);
                    else writeSpace(out);
                }
                writeZoneFooter(out);
            }
            System.out.println("生成字符數: " + count);
        }
    }

    // 輔助方法:寫入表頭、區標題、映射行、換行等 (省略具體 IO 細節)
    // 關鍵點:使用 CharsetDecoder/Encoder 替代手工查表,自動處理編碼邊界與擴展字符
}

關鍵技術點

  1. Charset.forName("GBK"):JDK 不直接支援 GB2312,GBK 為其超集,完美兼容。
  2. Decoder/Encoder 流水線:GBK bytes → CharBuffer (Unicode 字符) → UTF-16BE/UTF-8 bytes,標準化、無損轉換。
  3. 碼位有效性檢查:GB2312 存在大量未編碼碼位 (保留區、空洞),需依據國標範圍過濾 (如 isValidGB 方法)。
  4. 輸出格式:區位碼、GB 雙字節、Unicode (UTF-16BE)、UTF-8 三欄對照,便於人工核對與程序解析。

輸出示例片段

Q.W.   GB     Unicode   UTF-8
1601   B0A1   554A      E5 95 8A   啊
1602   B0A2   963F      E9 98 BF   阿
1603   B0A3   57C3      E5 9F 83   埃
...
5501   D7A1   9F5F      E9 BD 9F   齟 (二級漢字區起始)

現代替代方案

  • ICU4J:com.ibm.icu.text.CharsetDetector 自動探測編碼,CharsetConverter 高性能批量轉換。
  • Guava:Charsets.GBK、ByteSource.asCharSource(Charset) 簡化讀寫。
  • 標準庫:new String(gbBytes, "GBK") / uniString.getBytes("UTF-8") 滿足簡單場景。

應用場景

  • 舊系統遷移:數據庫字段 GBK → UTF-8 全量轉換驗證。
  • 編碼探測訓練數據生成。
  • 字體開發、輸入法詞庫構建需字符編碼對照。
  • 教學演示字符編碼原理。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved