汉字编码对照表(gb2312Big5GB2312)
汉字编码对照表(gb2312Big5GB2312)
⼀、汉字编码的种类
1、GB2312⼜称国标码,由国家标准总局发布,1981年5⽉1⽇实施,通⾏于⼤陆。新加坡等地也使⽤此编码。它是⼀个简化字的编码规范,当然也包括其他的符号、字母、⽇⽂假名等,共7445个图形字符,其中汉字占6763个。我们平时说6768个汉字,实际上⾥边有5个编码为空⽩,所以总共有6763个汉字。
GB2312规定“对任意⼀个图形字符都采⽤两个字节表⽰,每个字节均采⽤七位编码表⽰”,习惯上称第⼀个字节为“⾼字节”,第⼆个字节为“低字节”。GB2312中汉字的编码范围为,第⼀字节0xB0-0xF7(对应⼗进制为176-247),第⼆个字节0xA0-0xFE(对应⼗进制为160-254)。
GB2312将代码表分为94个区,对应第⼀字节(0xa1-0xfe);每个区94个位(0xa1-0xfe),对应第⼆字节,两个字节的值分别为区号值和位号值加32(2OH),因此也称为区位码。01-09区为符号、数字区,16-87区为汉字区(0xb0-0xf7),10-15区、88-94区是有待进⼀步标准化的空⽩区。
2、Big5⼜称⼤五码,主要为⾹港与台湾使⽤,即是⼀个繁体字编码。每个汉字由两个字节构成,第⼀个字节的范围
从0X81-0XFE(即129-255),共126种。第⼆个字节的范围不连续,分别为0X40-0X7E(即64-126),
0XA1-0XFE(即161-254),共157种。
3、GBK是GB2312的扩展,是向上兼容的,因此GB2312中的汉字的编码与GBK中汉字的相同。另外,GBK中还包含繁体字的编码,它与Big5编码之间的关系我还没有弄明⽩,好像是不⼀致的。GBK中每个汉字仍然包含两个字节,第⼀个字节的范围是0x81-0xFE(即129-254),第⼆个字节的范围是0x40-0xFE(即64-254)。GBK中有码位23940个,包含汉字21003个。
表1 汉字编码范围
名称第⼀字节第⼆字节
GB23120xB0-0xF7(176-247)0xA0-0xFE(160-254)
GBK0x81-0xFE(129-254)0x40-0xFE(64-254)
Big50x81-0xFE(129-255)0x40-0x7E(64-126)
0xA1-0xFE(161-254)
⼆、对汉字进⾏hash
为了处理汉字的⽅便,在查汉字的时候,我们通常会⽤到hash的⽅法,那怎么来确定⼀个汉字位置呢?这就和每种编码的排列有关了,这⾥主要给出⼀种hash函数的策略。
对于GB2312编码,设输⼊的汉字为GBword,我们可以采⽤公式(C1-176)*94 + (C2-161)确定GBindex。其中,C1表⽰第⼀字节,C2表⽰第⼆字节。具体如下:
GBindex = ((unsigned char)GBword.at(0)-176)*94 + (unsigned char)GBword.at(1) - 161;
之所以⽤unsigned char类型,是因为char是⼀个字节,如果⽤unsigend int,因为int是4个字节的,所以会造成扩展,导致错误。
对于GBK编码,设输⼊的汉字为GBKword,则可以采⽤公式  index=(ch1-0x81)*190+(ch2-0x40)-(ch2/128),其中ch1是第⼀字节,ch2是第⼆字节。
具体的,
GBKindex = ((unsigned char)GBKword[0]-129)*190 +
((unsigned char)GBKword[1]-64) - (unsigned char)GBKword[1]/128;
三、怎样判断⼀个汉字的是什么编码
直接根据汉字的编码范围判断,对于GB2312和GBK可⽤下⾯两个程序实现。
1、判断是否是GB2312
bool isGBCode(const string& strIn)
{
unsigned char ch1;
unsigned char ch2;
if (strIn.size() >= 2)
{
ch1 = (unsigned char)strIn.at(0);
ch2 = (unsigned char)strIn.at(1);
if (ch1>=176 && ch1<=247 && ch2>=160 && ch2<=254)
return true;
else return false;
}
else return false;
}
2、判断是否是GBK编码
bool isGBKCode(const string& strIn)
{
unsigned char ch1;
unsigned char ch2;
if (strIn.size() >= 2)
{
ch1 = (unsigned char)strIn.at(0);
ch2 = (unsigned char)strIn.at(1);
if (ch1>=129 && ch1<=254 && ch2>=64 && ch2<=254)
return true;
else return false;
}
else return false;
}
3、对于Big5
它的范围为:⾼字节从0xA0到0xFE,低字节从0x40到0x7E,和0xA1到0xFE两部分。判断⼀个汉字是
否是BIG5编码,可以如上对字符的编码范围判断即可。如何定位呢?那么也想象所有编码排列为⼀个⼆维坐标,纵坐标是⾼字节,横坐标是低字节。这样⼀⾏上的汉字个
数:(0x7E-0x40+1)+(0xFE-0xA1+1)=157。那么定位算法分两块,为:
if 0x40<=ch2<=0x7E: #is big5 char
index=((ch1-0xA1)*157+(ch2-0x40))*2
elif 0xA1<=ch2<=0xFE: #is big5 char
index=((ch1-0xA1)*157+(ch2-0xA1+63))*2汉字编码
对于第⼆块,计算偏移量时因为有两块数值,所以在计算后⾯⼀段值时,不要忘了前⾯还有⼀段值。0x7E-0x40+1=63。
四、如果判断⼀个字符是西⽂字符还是中⽂字符
⼤家知道西⽂字符主要是指ASCII码,它⽤⼀个字节表⽰。且这个字符转换成数字之后,该数字是⼤于0的,⽽汉字是两个字节的,第⼀个
字节的转化为数字之后应该是⼩于0的,因此可以根据每个字节转化为数字之后是否⼩于0,判断它是否是汉字。例如,设输⼊字为strin,则,
If (strin.at(0) < 0)
cout << ”是汉字” << endl;
else cout << ”不是汉字” << endl;
五、编码表下载
见附件

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。