现在的位置: 首页 > 综合 > 正文

GB2312 GBK BIG5

2014年03月14日 ⁄ 综合 ⁄ 共 4999字 ⁄ 字号 评论关闭

一、基本概念 
GB码 

全称是GB2312-80《信息交换用汉字编码字符集   基本集》,1980年发布,是中文信息处理的国家标准,在大陆及海外使用简体中文的地区(如新加坡等)是强制使用的唯一中文编码。P-Windows3.2和苹果OS就是以GB2312为基本汉字编码,   Windows   95/98则以GBK为基本汉字编码、但兼容支持GB2312。GB码共收录6763个简体汉字、682个符号,其中汉字部分:一级字3755,以拼音排序,二级字3008,以偏旁排序。该标准的制定和应用为规范、推动中文信息化进程起了很大作用。1990年又制定了繁体字的编码标准GB12345-90《信息交换用汉字编码字符集
  第一辅助集》,目的在于规范必须使用繁体字的各种场合,以及古籍整理等。该标准共收录6866个汉字(比GB2312多103个字,其它厂商的字库大多不包括这些字),纯繁体的字大概有2200余个。(2312集与12345集不是相交的。一个是简体,一个是繁体) 


BIG5编 

是目前台湾、香港地区普遍使用的一种繁体汉字的编码标准,包括440个符号,一级汉字5401个、二级汉字7652个,共计13060个汉字。Big-5   是一个双字节编码方案,其第一字节的值在   16   进制的   A0~FE   之间,第二字节在   40~7E   和   A1~FE   之间。因此,其第一字节的最高位是   1,第二字节的最高位则可能是
  1,也可能是   0。 



GBK编码(Chinese   Internal   Code   Specification) 

GBK编码(俗称大字符集)是中国大陆制订的、等同于UCS的新的中文编码扩展国家标准。GBK工作小组于1995年10月,同年12月完成GBK规范。该编码标准兼容GB2312,共收录汉字21003个、符号883个,并提供1894个造字码位,简、繁体字融于一库。Windows95/98简体中文版的字库表层编码就采用的是GBK,通过GBK与UCS之间一一对应的码表与底层字库联系。其第一字节的值在
  16   进制的   81~FE   之间,第二字节在   40~FE,除去xx7F一线。 


Unicode编码(Universal   Multiple   Octet   Coded   Character   Set) 

国际标准组织于1984年4月成立ISO/IEC   JTC1/SC2/WG2工作组,针对各国文字、符号进行统一性编码。1991年美国跨国公司成立Unicode   Consortium,并于1991年10月与WG2达成协议,采用同一编码字集。目前Unicode是采用16位编码体系,其字符集内容与ISO10646的BMP(Basic   Multilingual   Plane)相同。Unicode于1992年6月通过DIS(Draf
  International   Standard),目前版本V2.0于1996公布,内容包含符号6811个,汉字20902个,韩文拼音11172个,造字区6400个,保留20249个,共计65534个。 

二、一些注解 
在此解释一下我们常见的一些汉字内码转换工具: 
1、   最常见的是GB2Big5和Big52GB转换工具。这里的GB指是GB2312集。 
2、   GBK简体兼容GB2312字符集及其编码。不规范理解为GB就是GBK简体。 
3、   繁体不等同于Big5,在GBK集中也有繁体,GB12345集也有繁体。但这三者的汉字编码方式不同。Windows95/98/NT/2000(简体中)中使用的都是GBK字符集;繁体版使用的是Big5字符集,在简体版中无法正常显示Big5字符,繁体版无法显示GB字符。 
4、   在IE中,进入Big5码网站(如:台湾网站),如果安装有Big5字符集支持,IE会将Big5网页转换成GBK繁体显示,没有则是乱码。IE以GBK繁体显示时,在网页中输入的汉字应当是GBK繁体,以Big5码显示时(乱码),要输入Big5码字符(输入乱码?   先输入GBK简体----GB码,再使用小工具将其转换成Big5,拷贝,粘贴即可)。 
5、   常见的小工具中,可将Big5转换成GBK繁体的不多,可将GBK简体繁体相互转换的也不多。其原因是,他们是将GB2312字符集与Big5字符集建立了对应关系。 

三、内码转换原理及方法 
内码转换:就是在不同字符集之间建立一种对应关系。 
以GBK2Big5(简繁体都可) 
如:让字,在GBK中编码是C8C3。如果我们将GBK码表中的字符变成Big5码格式,则C8C3位上的应该是攍och   让攠字的Big5码字符攠琵攠(琵字不是GBK中的琵,而是攠让攠字的Big5码汉字在GBK环境中显示结果)。这样我们读出要转换的文字,在GBK(已经转换成Big5格式)码表中找到它的位置,取出该位置上的字符,将原字符替换即可。 
  
读写字符不是问题。关键是如何在码表文件中对该汉字进行定位和如何将纯GBK码表转换成Big5格式表示的GBK码表。
问题一、对汉字进行定位。 
GBK   代码表(按代码顺序排列)   81-87   88-8F   90-97   98-9F   A0-A7   A8-AF   B0-B7   B8-BF 
C0-C7   C8-CF   D0-D7   D8-DF   E0-E7   E8-EF   F0-F7   F8-FE 
81   0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F 
4   丂   丄   丅   丆   丏   丒   丗   丟   丠   両   丣   並   丩   丮   丯   丱 
5   丳   丵   丷   丼   乀   乁   乂   乄   乆   乊   乑   乕   乗   乚   乛   乢 
6   乣   乤   乥   乧   乨   乪   乫   乬   乭   乮   乯   乲   乴   乵   乶   乷 
7   乸   乹   乺   乻   乼   乽   乿   亀   亁   亂   亃   亄   亅   亇   亊     
8   亐   亖   亗   亙   亜   亝   亞   亣   亪   亯   亰   亱   亴   亶   亷   亸 
9   亹   亼   亽   亾   仈   仌   仏   仐   仒   仚   仛   仜   仠   仢   仦   仧 
A   仩   仭   仮   仯   仱   仴   仸   仹   仺   仼   仾   伀   伂   伃   伄   伅 
B   伆   伇   伈   伋   伌   伒   伓   伔   伕   伖   伜   伝   伡   伣   伨   伩 
C   伬   伭   伮   伱   伳   伵   伷   伹   伻   伾   伿   佀   佁   佂   佄   佅 
D   佇   佈   佉   佊   佋   佌   佒   佔   佖   佡   佢   佦   佨   佪   佫   佭 
E   佮   佱   佲   併   佷   佸   佹   佺   佽   侀   侁   侂   侅   來   侇   侊 
F   侌   侎   侐   侒   侓   侕   侖   侘   侙   侚   侜   侞   侟   価   侢     

  
以上是按代码顺序排列GBK码表,共126个区,每区190个汉字。汉字位置的计算如下: 
                          posit   =   (ch1   -   129)   *   190   +   (ch2   -   64)   -   (ch2/128);(第n   个汉字) 
                              posit   =   posit   *   2;   (第n个字节) 
  第一个问题就算搞定。 

问题二、将GBK码表用Big5来表示。 
我们可以利用现有的工具,如东方快车3000,将GBK码表转换成Big5的格式。但实际中有问题,因为GBK较Big5的汉字要多,那么在GBK中有的字符,而Big5中没有的字符在转换中可能被删除,那上面后码表定位就不能用了。而且实际上几乎无法定位。不过我在网上找到了一个以Big5表示的GBK码表的文本(可能是官方的),字符一个不缺。 
这个问题也搞定了。 


同样我们可以进行 
Big52GBKT(繁体),Big52GBKS(简体),GBKS2GBKT,GBKT2GBKS,GBK2BIG5的转化。这里给出Big5码表格式,和定位算法: 
BIG-5   代码表   A0-A7   A8-AF   B0-B7   B8-BF   C0-C7   C8-CF 
D0-D7   D8-DF   E0-E7   E8-EF   F0-F7   F8-FE 
        (已被转化成 
GBK)B0   0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F 
4   虔   蚊   蚪   蚓   蚤   蚩   蚌   蚣   蚜   衰   衷   袁   袂   衽   衹   記 
5   訐   討   訌   訕   訊   託   訓   訖   訏   訑   豈   豺   豹   財   貢   起 
6   躬   軒   軔   軏   辱   送   逆   迷   退   迺   迴   逃   追   逅   迸   邕 
7   郡   郝   郢   酒   配   酌   釘   針   釗   釜   釙   閃   院   陣   陡     
A       陛   陝   除   陘   陞   隻   飢   馬   骨   高   鬥   鬲   鬼   乾   偺 
B   偽   停   假   偃   偌   做   偉   健   偶   偎   偕   偵   側   偷   偏   倏 
C   偯   偭   兜   冕   凰   剪   副   勒   務   勘   動   匐   匏   匙   匿   區 
D   匾   參   曼   商   啪   啦   啄   啞   啡   啃   啊   唱   啖   問   啕   唯 
E   啤   唸   售   啜   唬   啣   唳   啁   啗   圈   國   圉   域   堅   堊   堆 
F   埠   埤   基   堂   堵   執   培   夠   奢   娶   婁   婉   婦   婪   婀     


定位方法: 
                      if   ((ch2   > =   64)&&(ch2   <=   126)) 
                      { 
                              posit   =   (ch1   -   160)   *   157   +   (ch2   -   64); 
                              posit   =   posit   *   2   -   1; 
        } 
                      else   if   ((ch2   > =   161)&&(ch2   <=   254)) 
                      { 
                              posit   =   (ch1   -   160)   *   157   +   62   +   (ch2   -   160); 
                              posit   =   posit   *   2   -   1; 
        } 

在这里给出GBK2Big5的C++Builder的程序:   


fGBK2Big5     =   fopen( "pureGBK2Big5byOrder.txt ",   "rb "); 

      unsigned   long   i,posit;//把gb码转换为gbkT 
      unsigned   char   ch1,ch2; 
      String       sContext; 
      char   chr; 

    sContext   =   Memo1-> Lines-> Text; 
      i=1; 
      while(i   <   sContext.Length()) 
      { 
              ch1   =   sContext[i]; 
              ch2   =   sContext[i+1]; 
  
              if   ((ch1   > =   129)&&(ch1   <=   254)) 
              { 
                      if   (((ch2   > =   64)&&(ch2   <   127))   ||((ch2   >   127)&&(ch2   <=   254))) 
                      { 
                              posit   =   (ch1   -   129)   *   190   +   (ch2   -   64)   -   (ch2/128); 
                              posit   =   posit   *   2; 
                              if   ((posit   >   23940*2)   ||   (posit   <   0)) 
                              { 
                                      i++; 
                                      continue; 
                              } 
                              fseek(fGBK2Big5,   posit   -   ftell(fGBK2Big5),   1); 
                              fread((void   *)(&chr),   sizeof(char),   1,   fGBK2Big5); 
                              sContext[i]   =   chr; 
                              fread((void   *)(&chr),   sizeof(char),   1,   fGBK2Big5); 
                              sContext[i+1]   =   chr; 
                              i   +=2; 
                      } 
                      else 
                      { 
                              i++; 
                      } 
              } 
              else 
              { 
                      i++; 
              } 
      } 

Memo1-> Lines-> Text=sContext;

抱歉!评论已关闭.