一、汉字编码的种类
汉字编码中现在主要用到的有三类c;包括GBKc;GB2312和Big5。
1、GB2312又称国标码c;由国家标准总局发布c;1981年5月1日实施c;通行于大陆。新加坡等地也使用此编码。它是一个简化字的编码规范c;当然也包括其他的符号、字母、日文假名等c;共7445个class="tags" href="/tags/TuXing.html" title=图形>图形字符c;其中汉字占6763个。我们平时说6768个汉字c;实际上里边有5个编码为空白c;所以总共有6763个汉字。
GB2312规定“对任意一个class="tags" href="/tags/TuXing.html" title=图形>图形字符都采用两个字节表示c;每个字节均采用七位编码表示”c;习惯上称第一个字节为“高字节”c;第二个字节为“低字节”。GB2312中汉字的编码范围为c;第一字节0xB0-0xF7(对应十进制为176-247)c;第二个字节0xA0-0xFE(对应十进制为160-254)。
GB2312将代码表分为94个区c;对应第一字节(0xa1-0xfe);每个区94个位(0xa1-0xfe)c;对应第二字节c;两个字节的值分别为区号值和位号值加32(2OH)c;因此也称为区位码。01-09区为符号、数字区c;16-87区为汉字区(0xb0-0xf7)c;10-15区、88-94区是有待进一步标准化的空白区。
2、Big5又称大五码c;主要为香港与台湾使用c;即是一个繁体字编码。每个汉字由两个字节构成c;第一个字节的范围从0X81-0XFE(即129-255)c;共126种。第二个字节的范围不连续c;分别为0X40-0X7E(即64-126)c;0XA1-0XFE(即161-254)c;共157种。
3、GBK是GB2312的class="tags" href="/tags/KuoZhan.html" title=扩展>扩展c;是向上兼容的c;因此GB2312中的汉字的编码与GBK中汉字的相同。另外c;GBK中还包含繁体字的编码c;它与Big5编码之间的关系我还没有弄明白c;好像是不一致的。GBK中每个汉字仍然包含两个字节c;第一个字节的范围是0x81-0xFE(即129-254)c;第二个字节的范围是0x40-0xFE(即64-254)。GBK中有码位23940个c;包含汉字21003个。
表1 汉字编码范围
名称 | 第一字节 | 第二字节 |
GB2312 | 0xB0-0xF7(176-247) | 0xA0-0xFE(160-254) |
GBK | 0x81-0xFE(129-254) | 0x40-0xFE(64-254) |
Big5 | 0x81-0xFE(129-255) | 0x40-0x7E(64-126) 0xA1-0xFE(161-254) |
二、对汉字进行hash
为了处理汉字的方便c;在查找汉字的时候c;我们通常会用到hash的方法c;那怎么来确定一个汉字位置呢?这就和每种编码的排列有关了c;这里主要给出一种hash函数的策略。
对于GB2312编码c;设输入的汉字为GBwordc;我们可以采用公式(C1-176)*94 + (C2-161)确定GBindex。其中c;C1表示第一字节c;C2表示第二字节。具体如下:
GBindex = ((unsigned char)GBword.at(0)-176)*94 + (unsigned char)GBword.at(1) - 161;
之所以用unsigned char类型c;是因为char是一个字节c;如果用unsigend intc;因为int是4个字节的c;所以会造成class="tags" href="/tags/KuoZhan.html" title=扩展>扩展c;导致错误。
对于GBK编码c;设输入的汉字为GBKwordc;则可以采用公式 index=(ch1-0x81)*190+(ch2-0x40)-(ch2/128)c;其中ch1是第一字节c;ch2是第二字节。
具体的c;
GBKindex = ((unsigned char)GBKword[0]-129)*190 +
((unsigned char)GBKword[1]-64) - (unsigned char)GBKword[1]/128;
三、怎样判断一个汉字的是什么编码
直接根据汉字的编码范围判断c;对于GB2312和GBK可用下面两个程序实现。
1、判断是否是GB2312
bool isGBCode(const class="tags" href="/tags/STRING.html" title=string>string& strIn)
{
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 class="tags" href="/tags/STRING.html" title=string>string& strIn)
{
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到0xFEc;低字节从0x40到0x7Ec;和0xA1到0xFE两部分。判断一个汉字是否是BIG5编码c;可以如上对字符的编码范围判断即可。如何定位呢?那么也想象所有编码排列为一个二维坐标c;纵坐标是高字节c;横坐标是低字节。这样一行上的汉字个数:(0x7E-0x40+1)+(0xFE-0xA1+1)=157。那么定位class="tags" href="/tags/SuanFa.html" title=算法>算法分两块c;为:
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
对于第二块c;计算偏移量时因为有两块数值c;所以在计算后面一段值时c;不要忘了前面还有一段值。0x7E-0x40+1=63。
四、如果判断一个字符是西文字符还是中文字符
大家知道西文字符主要是指ASCII码c;它用一个字节表示。且这个字符转换成数字之后c;该数字是大于0的c;而汉字是两个字节的c;第一个字节的转化为数字之后应该是小于0的c;因此可以根据每个字节转化为数字之后是否小于0c;判断它是否是汉字。
If (strin.at(0) < 0)
cout << ”是汉字” << endl;
else cout << ”不是汉字” << endl;
五、编码表下载
GBK编码表c;下载
GB2312编码表c;下载