序言
这本手册用表格列出了 GB2312 汉字国家标准字符集的全部字符和编码,以及每个 字符所对应的 Unicode 编码。同时也列出了从 Unicode 到 GB2312 转换表。这些 表格的程式制作也收录在这本手册中。
修改记录:
第 3.05 版,二○○四年,局部修改。
第 3.00 版,二○○三年,整理成打印版。
第 2.00 版,一九九九年,整理成网页。
第 1.00 版,一九九七年,初稿完成。
阅读记录:
到2006年为止,本书已被阅读 72,409 次。
到2004年为止,本书已被阅读 4,721 次。
版权声明:
版权所有 1997 - 2007 杨和荣。
允许转载和使用,但必须保留版权声明
GB2312 字符集和编码说明
GB2312 字符集
GB2312 是汉字字符集和编码的代号,中文全称为“信息交换用汉字编码字符集”, 由中华人民共和国国家标准总局发布,一九八一年五月一日实施。GB 是“国标” 二字的汉语拼音缩写。
GB2312 字符集 (character set) 只收录简化字汉字,以及一般常用字母和符号, 主要通行于中国大陆地区和新加坡等地。
GB2312 共收录有 7445 个字符,其中简化汉字 6763 个,字母和符号 682 个。
GB2312 将所收录的字符分为 94 个区,编号为 01 区至 94 区;每个区收录 94 个字符,编号为 01 位至 94 位。GB2312 的每一个字符都由与其唯一对应的区号 和位号所确定。例如:汉字“啊”,编号为 16 区 01 位。
GB2312 字符集的区位分布表:
  区号    字数    字符类别
    01      94    一般符号
    02      72    顺序号码
    03      94    拉丁字母
    04      83    日文假名
    05      86    Katakana
    06      48    希腊字母
    07      66    俄文字母
    08      63    汉语拼音符号
    09      76    图形符号
10-15            备用区
16-55    3755    一级汉字,以拼音为序
56-87    3008    二级汉字,以笔划为序
88-94            备用区
这本手册列出了 GB2312 的全部字符和它们的区位号。
GB2312 编码
GB2312 原始编码 (encoding) 是对所收录的每个字符都用两个字节 (byte) 表示。 第一字节为“高字节”,由字符的区号值加上 32 而形成;第二字节为“低字节”, 由字符的位号值加上 3
2 而形成。例如:汉字“啊”,编号为 16 区 01 位。它的 高字节为 16 + 32 = 48 (0x30),低字节为 01 + 32 = 33 (0x21),合并而成的编 码为 0x3021。
在区位号值上加 32 的原因大慨是为了避开低值字节区间。
由于 GB2312 原始编码与 ASCII 编码的字节有重叠,现在通行的 GB2312 编码是 在原始编码的两个字节上各加 128 修改而形成。例如:汉字“啊”,编号为 16 区 01 位。它的原始编码为 0x3021,通行编码为 0xB0A1。
如果不另加说明,GB2312 常指这种修改过的编码。
这本手册列出了 GB2312 的全部字符和它们的编码。
GB2312 与 Unicode 的关系
GB2312 字符集是 Unicode 字符集的一个子集。这也就是说,GB2312 所收录的每 一个字符都收录在 Unicode 之中。
但是 GB2312 编码和 Unicode 编码确没有什么相同之处。同一个汉字,它的 GB2312 编码
和 Unicode 编码确毫不相同。例如:汉字“啊”,它的 GB2312 编码为 0xB0A1,但是它的 Unicode 编码为 0x554A。
这本手册为 GB2312 的每一个字符列出了它所对应的 Unicode 编码和 UTF-8 (Unicode Transformation Format - 8-bit) 编码。
从 GB2312 到 Unicode 转换表制作程式 
这本手册里的字符与汉字编码列表由下面的程式所生成。
/**
* GB2312Unicde.java
* Copyright (c) 1997-2003 by Dr. Herong Yang
*/
import java.io.*;
import java.nio.*;
import java.nio.charset.*;
class GB2312Unicde {
  static OutputStream out = null;
  static char hexDigit[] = {'0', '1', '2', '3', '4', '5', '6', '7',
                            '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
  static int b_out[] = {201,267,279,293,484,587,625,657,734,782,827,
      874,901,980,5590};
  static int e_out[] = {216,268,280,294,494,594,632,694,748,794,836,
      894,903,994,5594};
  public static void main(String[] args) {
unicode字符转中文
      try {
        out = new FileOutputStream("gb2312.gb");
        writeCode();
        out.close();
      } catch (IOException e) {
        System.out.String());
      }
  }
  public static void writeCode() throws IOException {
      boolean reserved = false;
      String name = null;
      // GB2312 is not supported by JDK. So I am using GBK.
      CharsetDecoder gbdc = Charset.forName("GBK").newDecoder();
      CharsetEncoder uxec = Charset.forName("UTF-16BE").newEncoder();
      CharsetEncoder u8ec = Charset.forName("UTF-8").newEncoder();
      ByteBuffer gbbb = null;
      ByteBuffer uxbb = null;
      ByteBuffer u8bb = null;
      CharBuffer cb = null;
      int count = 0;
      for (int i=1; i<=94; i++) {
        // Defining row settings
        if (i>=1 && i<=9) {
            reserved = false;
            name = "Graphic symbols";
        } else if (i>=10 && i<=15) {
            reserved = true;
            name = "Reserved";
        } else if (i>=16 && i<=55) {
            reserved = false;
            name = "Level 1 characters";
        } else if (i>=56 && i<=87) {
            reserved = false;
            name = "Level 2 characters";
        } else if (i>=88 && i<=94) {
            reserved = true;
            name = "Reserved";
        }
        // writing row title
        writeln();
        writeString("<p>");
        writeNumber(i);
        writeString(" Row: "+name);
        writeln();
        writeString("</p>");
        writeln();
        if (!reserved) {
            writeln();
            writeHeader();
          // looping through all characters in one row
            for (int j=1; j<=94; j++) {
              byte hi = (byte)(0xA0 + i);
              byte lo = (byte)(0xA0 + j);
              if (validGB(i,j)) {