内码转换技术

一、基本概念
·    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位上的应该是” 让”字的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;



以上很多资料来源于网路灯塔的参考资料(http://www.haiyan.com/steelk/navigator/ref/gbindex1.htm)。
要5个码表,和源程序的支声  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值