早期中文系統常需在 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 替代手工查表,自動處理編碼邊界與擴展字符
}
GBK bytes → CharBuffer (Unicode 字符) → UTF-16BE/UTF-8 bytes,標準化、無損轉換。isValidGB 方法)。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 齟 (二級漢字區起始)
com.ibm.icu.text.CharsetDetector 自動探測編碼,CharsetConverter 高性能批量轉換。Charsets.GBK、ByteSource.asCharSource(Charset) 簡化讀寫。new String(gbBytes, "GBK") / uniString.getBytes("UTF-8") 滿足簡單場景。