说明
GB2312是第一个汉字编码国家标准
GB 2312 标准由中国国家标准总局 1980 年发布,GB 即国标,共收录 6763 个汉字,其中一级汉字 3755 个,二级汉字 3008 个。
- GB 2312 的出现,基本满足了汉字的计算机处理需要,它所收录的汉字已经覆盖中国大陆 99.75% 的使用频率。
- 对于人名、古汉语等方面出现的罕用字,GB 2312 不能处理,这导致了后来 GBK 及 GB 18030 汉字字符集的出现。
GB2312编码表有个值得注意的点,这个表中也有一些数字和字母,与ASCII里面的字母非常像。例如A3B2对应的是数字2(如下图),但是ASCII里面50(十进制)对应的也是数字2。他们的区别就是输入法中所说的“半角”和“全角”。全角的数字2占两个字节。
GB 2312 兼容 ASCII 码(0 - 127),之后对任意一个图形字符都采用两个字节表示,高位字节和低位字节都大于 127。
GB 2312 字符集分成 94 个区,每区有 94 个位,分别对应第一字节和第二字节,这种表示方式也称为区位码。
- 01-09 区为特殊符号
- 10-15 区为用户自定义符号区(未编码)
- 16-55 区为一级汉字,按拼音排序,共 3755 个
- 56-87 区为二级汉字,按部首/笔画排序,共 3008 个
- 88-94 区为用户自定义汉字区(未编码)
用16进制来表示的话,GB2312的编码范围是0xA1A1-0xFEFE,去掉未定义的区域之后可以理解为实际编码范围是0xA1A1-0xFEFE。其中第一个字节即前两个字符代表区,第二个字节代表位。
当我们查询0xB0A1时,需要在B0区,查找A1位.
0xB0-0xA1=0x0E=15
由于是从B0开始为第一个区,所以15+1=16区。
0xA1-0xA0=0x01=1
由于是从A0开始为第一位,所以1+1=2位.
即第16区的第2个字符。
查表 GB2312 编码表 - 在线工具
即在GB2312中,0xB0A1代表汉字'啊'。以后噫吁嚱的时候可以喊"0xb0a1(啊)0x21(半角字符!)"。
A1区开始A2/A3/一直到FE区一共94个区。
每个区从A1到FE共94位
示例
C++示例:通过赋值16进制编码,显示汉字'你'
#include <iostream>
int main()
{
char gb2312[3]="";
gb2312[0] = 0xc4;
gb2312[1] = 0xe3;
std::cout << gb2312 <<std::endl;
system("pause");
}
示例二:显示'你好'
#include <iostream>
int main()
{
char gb2312[5]="";
gb2312[0] = 0xc4;
gb2312[1] = 0xe3;
gb2312[2] = 0xBA;
gb2312[3] = 0xC3;
std::cout << gb2312 <<std::endl;
system("pause");
}
现在,我们将0xd76f赋值进去,可以看到一个比较生僻的字'護'显示了出来
实际上,这个字并不存在于gb2312中,我们回顾一下gb2312的编码范围:GB2312的编码范围是0xA1A1-0xFEFE。可以发现,0xd76f不属于gb2312的编码范围,第二个字字节6f是小于编码范围中第二个字节的A1的,转换成二进制就是
01101111(0x6f)
和
10100001(0xa1)~11111110(0xfe)
可以明显看出,01101111是不在这个范围中的。
但是我们运行程序,这个'護'不还是正常显示了吗?这是为什么呢?
这是因为windows下,控制台的中文系统代码页默认是GBK,而GBK中是包含这个字的,所以这个字是可以正常显示在控制台中的。
在C++中,使用WindowsAP函数SetConsoleOutputCP可以设置控制台的代码页。通过SetConsoleOutputCP(20936);将默认的GBK修改为GB2312(GB2312-80)
gb2312-80编码显示字符:
#include <iostream>
#include <Windows.h>
int main()
{
SetConsoleOutputCP(20936);
char gb2312[5] = "";
gb2312[0] = 0xd7;
gb2312[1] = 0x6f;
gb2312[2] = 0xBA;
gb2312[3] = 0xC3;
std::cout << gb2312 << std::endl;
system("pause");
}
可以看到,本来可以正常显示的汉字'護'在控制台中显示成了?,后面属于gb2312的汉字'好'还可以正常显示出来。关于这个现象和代码页的更多内容,请期待后续章节中的“编码列表是什么?如何修改windows控制台的代码页编码?”
下一篇 GBK编码