GB2312、GBK、Big5汉字编码

news/2024/7/8 5:37:01 标签: string, 图形, 扩展, 算法, c
cle class="baidu_pl">
cle_content" class="article_content clearfix">
content_views" class="htmledit_views">  由于常常要和汉字处理打交道࿰c;因此࿰c;我常常受到汉字编码问题的困扰。在不断的打击与坚持中࿰c;也积累了一点汉字编码方面的经验࿰c;想和大家一起分享。

一、汉字编码的种类

    汉字编码中现在主要用到的有三类࿰c;包括GBK࿰c;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 汉字编码范围

cellspacing="0" cellpadding="0">

名称

第一字节

第二字节

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;设输入的汉字为GBword࿰c;我们可以采用公式(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 int࿰c;因为int是4个字节的࿰c;所以会造成class="tags" href="/tags/KuoZhan.html" title=扩展>扩展࿰c;导致错误。

       对于GBK编码࿰c;设输入的汉字为GBKword࿰c;则可以采用公式   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)

{

    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 class="tags" href="/tags/STRING.html" title=string>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࿰c;低字节从0x40到0x7E࿰c;和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;因此可以根据每个字节转化为数字之后是否小于0࿰c;判断它是否是汉字。

    例如࿰c;设输入字为strin࿰c;则࿰c;

     If (strin.at(0) < 0)

       cout << ”是汉字” << endl;

     else cout << ”不是汉字” << endl;

 

五、编码表下载

   GBK编码表࿰c;下载

   GB2312编码表࿰c;下载

 

cle>

http://www.niftyadmin.cn/n/1535491.html

相关文章

常用字符集编码详解:ASCII 、GB2312、GBK、GB18030、UTF-8、unicode

ASCII ASCII码是7位编码&#xff0c;编码范围是0x00-0x7F。ASCII字符集包括英文字母、阿拉伯数字和标点符号等字符。其中0x00-0x20和0x7F共33个控制字符。 只支持ASCII码的系统会忽略每个字节的最高位&#xff0c;只认为低7位是有效位。HZ字符编码就是早期为了在只支持7位AS…

字符集和编码方式

一 预备知识 1&#xff0c;字符&#xff1a;字符是抽象的最小文本单位。它没有固定的形状&#xff08;可能是一个字形&#xff09;&#xff0c;而且没有值。“A”是一个字符&#xff0c;“€”&#xff08;德国、法国和许多其他欧洲国家通用货币的标志&#xff09;也是一个字符…

Java入门——(4)多线程

Java入门——&#xff08;4&#xff09;多线程关键词&#xff1a;线程、Thread、Runnable、sleep()、yield()、join()、同步一、线程的概述在一个操作系统中&#xff0c;每个独立执行的程序都可以称为一个进程&#xff0c;也就是“正在运行的程 序”。而在进程中还可以有多个执…

自然语言处理入门书

如果你刚接触自然语言处理并对她感兴趣&#xff0c;最好读几本这方面的书籍&#xff0c;除了能让你知道自然语言处理各个领域是干什么的外&#xff0c;还能培养一下NLP的感觉。 以下四本书是我读研期间阅读和接触过的&#xff0c;如果您还有好书推荐&#xff0c;欢迎补充。 1、…

转:LRU算法

LRU是Least Recently Used的缩写&#xff0c;即最近最少使用页面置换算法&#xff0c;是为虚拟页式存储管理服务的&#xff0c;是根据页面调入内存后的使用情况进行决策了。由于无法预测各页面将来的使用情况&#xff0c;只能利用“最近的过去”作为“最近的将来”的近似&#…

自然语言处理应用方向和专业英语

自然语言处理是计算机科学领域与人工智能领域中的一个重要方向。它研究能实现人与计算机之间用自然语言进行有效通信的各种理论和方法。自然语言处理处理的内容涉及到语言的各个层次&#xff0c;包括字、词、句、段落、篇章和语义。 目前自然语言处理的主要研究和应用方向有&a…

【树莓派】树莓派常用的一些源

树莓派更新或者下载一些软件资源的话&#xff0c;需要从国外下载&#xff0c;比较慢。 阿里云的镜像源: http://mirrors.aliyun.com/raspbian/raspbian/ 这是一些国内的源&#xff0c;可以参考使用&#xff1a; #替换国内源#中山大学 deb http://mirror.sysu.edu.cn/raspbian/r…

Linux中.a,.la,.o,.so文件的意义和编程实现

Linux下文件的类型是不依赖于其后缀名的&#xff0c;但一般来讲&#xff1a;   .o,是目标文件,相当于windows中的.obj文件   .so 为共享库,是shared object,用于动态连接的,和dll差不多   .a为静态库,是好多个.o合在一起,用于静态连接   .la为libtool自动生成的一些共享…