《汉字区位码查询与算法.doc》由会员分享,可在线阅读,更多相关《汉字区位码查询与算法.doc(32页珍藏版)》请在三一办公上搜索。
1、汉字区位码查询与算法要从事学术研究,一定要学好数学,数学可以把对事物的描述精确化。tuenhai为什么要学习编程?其中一个原因就是利用编程工具进行一些数学运算。记得大约10年前,那时tuenhai还没有电脑,要进行大数计算,怎么办?那时就到处打听,哪里有数位多一些的计算器。一般计算器只有8位,多一些的12位,还是不够用。有一次和故人到大城市,总算打听到了超过12位的计算器,考虑再三,还是没有买下来(不知故人还有没有记得这件事,毕竟过去这么多年了)。父亲把我们以前读过的教材,练习本都保存着,我把粘满灰尘的数学教材找出来,放在我的书房,有时还会去随便翻翻。现在学校教育是彻头彻尾的失败。教育没有和实
2、际结合,毕业不久,学过的知识就很多交还给老师了。想起来,学校教育至少浪费了我5年光阴,工作中又至少浪费了我8年光阴,从出生到现在,竟有近一半时间浪费掉了,实在可怕。把学校教育批评得一无是处,那么理想的教育应该是怎么样的呢?理想的教育应该是一切学科相通的,只有这样,知识才能活起来,学而即用,不用死记。这样的学习,只有快乐,没有痛苦。这样的学校教育可谓是完美,在这个不完美的世界可能永远不会实现。就象中医,这么多人说要发扬真正的中医,但现代人没有这个福气,连伪中医都要衰落,何况真中医。现代小火神为什么不写书,或许有深机在焉。一切学科相通,从而理解这个世界,这个题目太大了,tuenhai()也只是玩味
3、了一点点。这里只讨论一下用编程的方法数字与汉字的转换,同时也附录一些资料,方便研究。tuenhai所用获得汉字或字符对应的区位符Function quwei(ByVal xAs String)As Stringx=Asc(x)Asc返回输入字符的码位或字符代码。对于单字节字符集(SBCS),返回值范围为0到255;对于双字节字符集(DBCS),返回值范围为-32768到32767。对于单字节ASCII字符的图表,请参见ASCII字符代码。x=Hex(x)返回表示数字的十六进制值的字符串。刘=FFFFC1F5,前面的4个F去掉,得到16进制的内码。16进制的C=10进制的12 Dim str A
4、s String str=Format(CDec(&H&Strings.Mid(x,5,2)-160,00)&Format(CDec(&H&Strings.Mid(x,7,2)-160,00)Strings.Mid(x,5,2)得到16进制的内码,刘内码高位=C1CDec(&H&str)转换成10进制内码,&H表示16进制刘内码高位=193-160得到10进制区码,刘区码是33Format(decQu,00)格式化为两位数表示Return str End FunctionGB2312的原文还是区位码,从区位码到内码,需要在高字节和低字节上分别加上A0,在DBCS中,GB内码的存储格式始终是bi
5、g endian,即高位在前。区位码是与汉字一一对应的编码,用四位数字表示,前两位从01到94称区码,后两位从01到94称位码。一个汉字的前一半是ASC码为160+区码的字符,后一半是ASC码为160+位码的字符。例如:刘的区位码是3385,其意为区码33位码85,它是由ASC码为160+33=193和160+85=245的两个字符组成。tuenhai所用获得区位符对应汉字或字符Function hanzi(ByVal xAs String)As StringOn Error Resume Next Dim str As String str=Chr(&H&Hex(Val(Strings.Le
6、ft(x,2)+160)&Hex(Val(Strings.Right(x,2)+160)Return(str)End FunctionChr使用System.Text命名空间中的Encoding类来确定当前线程使用的是单字节字符集(SBCS)还是双字节字符集(DBCS)。然后将CharCode作为相应字符集中的码位。对于SBCS字符,范围为0到255,对于DBCS字符,范围为-32768到65535。ChrW以CharCode作为Unicode码位。其范围与当前线程的区域性和代码页设置无关。-32768到-1范围内的值的处理方式与+32768到+65535范围内的值相同。(更多文章请访问 20
7、060427剡)汉字区位码查询,汉字区位码查询系统,区位码输入法下载,姓名区位码查询,汉字区位码下载,汉字区位码软件,电话号码区位码查询,什么是汉字区位码,电话区位码查询,区位输入法下载,城市的区位因素,手机号码区位查询,农业的区位选择,高考区位号查询,重庆高考区位号,工业的区位选择,汉字区位输入法,汉字区位代码表,区位日语输入法下载,汉字区位代码查询附录:从汉字到区位码的转换学校要我们填写毕业生的情况表,机读卡那种,姓名要用区位码.我想如果用程序来查询的话,就是数据库查找,我想编一个应该很简单的,就上网看看有没有类似的程序,然后我再用它的数据库自己实现一个,可让我查到了一个文章讲如何实现从汉
8、字到区位码的转换,呵呵,可以不用数据库了.区位码是与汉字一一对应的编码,用四位数字表示,前两位从01到94称区码,后两位从01到94称位码。一个汉字的前一半是ASC码为160+区码的字符,后一半是ASC码为160+位码的字符。例如:刘的区位码是3385,其意为区码33位码85,它是由ASC码为160+33=193和160+85=245的两个字符组成。我用简单的控制台程序实现如下#i nclude#i nclude void main()char i64;while(1)cout输入单个字母退出cin i;if(strlen(i)=1)break;for(int j=0;j cout(ij+96
9、)*100+ij+1+96如何随机生成指定数目的国标汉字?为了使每一个汉字有一个全国统一的代码,1980年,我国颁布了第一个汉字编码的国家标准:GB2312-80信息交换用汉字编码字符集基本集,这个字符集是我国中文信息处理技术的发展基础,也是目前国内所有汉字系统的统一标准。由于国标码是四位十六进制,为了便于交流,大家常用的是四位十进制的区位码。所有的国标汉字与符号组成一个9494的矩阵。在此方阵中,每一行称为一个区,每一列称为一个位,因此,这个方阵实际上组成了一个有94个区(区号分别为0 1到94)、每个区内有94个位(位号分别为01到94)的汉字字符集。一个汉字所在的区号和位号简单地组合在一
10、起就构成了该汉字的区位码。在汉字的区位码中,高两位为区号,低两位为位号。在区位码中,01-09区为682个特殊字符,1687区为汉字区,包含6763个汉字。其中16-55区为一级汉字(3755个最常用的汉字,按拼音字母的次序排列),56-87区为二级汉字(3008个汉字,按部首次序排列)。所以,当我们需要n个任意汉字时,我们不必建一个全部汉字表,而是利用区位码实现常用汉字的提取。下面的代码可以实现任意数目汉字的生成:Private Sub getrndhanzi(ByVal nAs Integer)Dim s()As String,i As Integer Dim temp1 As Integ
11、er,temp2 As Integer ReDim s(1 To n)Randomize For i=1 To ntemp1=16+Int(Rnd*72)If temp1=55 Then temp2=Int(Rnd*90)一级汉字从1601-1694,1701-1794,.5401-5494,5501-5589,共94*40-5=3755个汉字Else temp2=Int(Rnd*95)二级汉字从5601-5694,5701-5794,.8601-8694,8701-8794,共94*32=3008个汉字End If s(i)=Chr(&H&Hex(temp1+160)&Hex(temp2+1
12、60)Next Debug.Print Join(s,)输出End Sub Private Sub Command1_Click()Dim iAs Integer For i=1 To 25分别生成1-25个任意汉字getrndhanzi iNext End Sub输出:腿夫敞途罨椽涅搦侄铽榨藸禒艟球枵舟斟盯滩桫狲暗田苫撂蕾岢冠澧炫鲼噘惺馘柘巧愁炔哔臆策籼锭昏紶假媪慈乘嘎肤景濡薤呋刨锺灰榉懋唇弱献囟垤均耋撤阗驿迩愍殒埚砸宕薅蒹翦俄形碌哧烀爝懒缭嫔捭浑瑾砜疬哜遒濂勾彐綘珩苓就萌炳光椁旖趁鲲颀壕狁媪暑额忾帷淤黹湫熏裤降旺廓淳傻蜕脬荪色注紫劾吾陶沥瑗骶埴于喃刮瘿突赅斛简铨觞抨唼格鸽乜衍夙菀鲡败陆褐哙
13、苑滓淆踵讫头绑德泠婷岙湔池桨郅峁汩卒控诉刍镗椎鬣越嫉义懂聂其定鳓脯膪巯吐昏罚返抖陵沌戗喘茺缂废雾旯浠疼赃勋妓鳟埏帮盂蕹朐裂祆膻拌脎威纯宛免作绣稞涑枭搬怿旦熨呈弃驰翔聚饰栩燧艴氢贫豕源髑乍蚍夏己履毕芤毁篑子褊崖坏忑霉钿瘢驵迁裨獬纷胚桨衫蹒疯祧武琢吣酃踱免逘浊顸坐磬挫郐婶缪锰拽技薯帙陕槲逗蜱嘧雌怙诖椭踉盔锍认致暝榴蘖逆捻螨噬附:汉字与区位码转换代码:Function quwei(ByVal xAs String)As Stri ng获得某汉字或字符对应的的区位码If Asc(x)=0 Then Exit Function x=Hex(Asc(x)quwei=Format(CDec(&H&Left(
14、x,2)-160,00)&Format(CDec(&H&Right(x,2)-160,00)End Function Function hanzi(ByVal xAs String)As String获得某区位码对应汉字或字符hanzi=Chr(&H&Hex(Val(Left(x,2)+160)&Hex(Val(Right(x,2)+160)End Function经验总结-字符串与编码这几个月作手机短信的项目,碰到了很多字符编码的问题,真头痛。经过多番资料的搜索、亲手尝试和高人的指点,现在好像没那么迷惘了。现作了一些总结跟大家分享(有误之处请指点)首先应该把字节数组看成是String的载体。
15、dot Net使用的字符串String是Unicode编码的;它也是以Unicode编码的形式显示字符串。以下是用自己语言对几个常用函数的说明:(自己总结的,反正看不明MSDN)bytes=System.Text.Encoding.Unicode.GetBytes(str)作用:把str的载体作Unicode-Unicode的编码转换-也就是没有对载体作任何的转换。因些使用此函数可以得代表该String载体的字节数组。str=System.Text.Encoding.Unicode.GetString(bytes)作用:对字节数组作Unicode-Unicode的编码转换-即没有转换,把经过转
16、换后的字节数组作为str的载体。bytes=System.Text.Encoding.Utf8.GetBytes(str)作用:把str的载体作Utf8-Unicode的编码转换。返回的是经过转换后的字符数组str=System.Text.Encoding.Utf8.GetString(bytes)作用:对字节数组作Gb2312-Unicode的编码转换,把经过转换后的字节数组作为str的载体。bytes=System.Text.Encoding.GetEncoding(GB2312).GetBytes(str)作用:把str的载体作Gb2312-Unicode的编码转换。返回的是经过转换后的
17、字符数组str=System.Text.Encoding.GetEncoding(GB2312).GetString(bytes)作用:对字节数组作Gb2312-Unicode的编码转换,把经过转换后的字节数组作为str的载体。如此类推bytes=System.Text.Encoding.GetEncoding(XXX).GetBytes(str)作用:把str的载体作XXX-Unicode的编码转换。返回的是经过转换后的字符数组str=System.Text.Encoding.GetEncoding(XXX).GetString(bytes)作用:对字节数组作XXX-Unicode的编码转换
18、,把经过转换后的字节数组作为str的载体。这里是我收集的一些有关字符编码的资料:还有:根据Unicode编码查其对应字符的字形、Utf8、汉字区位码等Unicode与Gb2312的对照表与Gbk对照表用C#生成中文汉字验证码的基本原理前几天去申请免费QQ号码,突然发现申请表单中的验证码内容换成了中文,这叫真叫我大跌眼镜感到好笑,Moper上的猫儿们都大骂腾讯采用中文验证码。_我不得不佩服腾讯为了防止目前网络上横行的QQ号码自动注册机而采取中文验证码的手段。仔细想了想感觉用程序生成随机的中文验证码并不是很难,下面就来介绍一下使用C#生成随机的中文汉字的原理。1、汉字编码原理到底怎么办到随机生成汉
19、字的呢?汉字从哪里来的呢?是不是有个后台数据表,其中存放了所需要的所有汉字,使用程序随机取出几个汉字组合就行了呢?使用后台数据库先将所有汉字存起来使用时随机取出,这也是一种办法,但是中文汉字有这么多,怎么来制作呢?其实可以不使用任何后台数据库,使用程序就能做到这一切。要知道如何生成汉字,就得先了解中文汉字的编码原理。1980年,为了使每一个汉字有一个全国统一的代码,我国颁布了第一个汉字编码的国家标准:GB2312-80信息交换用汉字编码字符集基本集,简称GB2312,这个字符集是我国中文信息处理技术的发展基础,也是国内所有汉字系统的统一标准。到了后来又公布了国家标准GB18030-2000信息
20、交换用汉字编码字符集基本集的扩充,简称GB18030,编程时如果涉及到编码和本地化的朋友应该对GB18030很熟悉。这是是我国继GB2312-1980和GB13000-1993之后最重要的汉字编码标准,同时也是未来我国计算机系统必须遵循的基础性标准之一。目前在中文WINDOWS操作系统中,.NET编程中默认的的代码页就是GB18030简体中文。但是事实上如果生成中文汉字验证码只须要使用GB2312字符集就已经足够了。字符集中除了我们平时大家都认识的汉字外,也包含了很多我们不认识平时也很少见到的汉字。如果生成中文汉字验证码中有很多我们不认识的汉字让我们输入,对于使用拼音输入法的朋友来说可不是好事
21、,五笔使用者还能勉强根据汉字的长相打出来,呵呵!所以对于GB2312字符集中的汉字我们也不是全都要用。中文汉字字符可以使用区位码来表示,见汉字区位码表汉字区位码代码表其实这两个表是同一回事,只不过一个使用十六进制分区表示,一个使用区位所在的数字位置表示。例如好字的十六进制区位码是ba c3,前两位是区域,后两位代表位置,ba处在第26区,好处在此区汉字的第35位也就是c3位置,所以数字代码就是2635。这就是GB2312汉字区位原理。根据汉字区位码表我们可以发现第15区也就是AF区以前都没有汉字,只有少量符号,汉字都从第16区B0开始,这就是为什么GB2312字符集都是从16区开始的。2、.N
22、et程序处理汉字编码原理分析在.Net中可以使用System.Text来处理所有语言的编码。在System.Text命名空间中包含众多编码的类,可供进行操作及转换。其中的Encoding类就是重点处理汉字编码的类。通过在.NET文档中查询Encoding类的方法我们可以发现所有和文字编码有关的都是字节数组,其中有两个很好用的方法:Encoding.GetBytes()方法将指定的String或字符数组的全部或部分内容编码为字节数组Encoding.GetString()方法将指定字节数组解码为字符串。没错我们可以通过这两个方法将汉字字符编码为字节数组,同样知道了汉字GB2312的字节数组编码也
23、就可以将字节数组解码为汉字字符。通过对好字进行编码为字节数组后Encoding gb=System.Text.Encoding.GetEncoding(gb2312);object bytes=gb.Encoding.GetBytes(好);发现得到了一个长度为2的字节数组bytes,使用string lowCode=System.Convert.ToString(bytes0,16);/取出元素1编码内容(两位16进制)string hightCode=System.Convert.ToString(bytes1,16);/取出元素2编码内容(两位16进制)之后发现字节数组bytes16进制
24、变码后内容竟然是ba,c3,刚好是好字的十六进制区位码(见区位码表)。因此我们就可以随机生成一个长度为2的十六进制字节数组,使用GetString()方法对其进行解码就可以得到汉字字符了。不过对于生成中文汉字验证码来说,因为第15区也就是AF区以前都没有汉字,只有少量符号,汉字都从第16区B0开始,并且从区位D7开始以后的汉字都是和很难见到的繁杂汉字,所以这些都要排出掉。所以随机生成的汉字十六进制区位码第1位范围在B、C、D之间,如果第1位是D的话,第2位区位码就不能是7以后的十六进制数。在来看看区位码表发现每区的第一个位置和最后一个位置都是空的,没有汉字,因此随机生成的区位码第3位如果是A的
25、话,第4位就不能是0;第3位如果是F的话,第4位就不能是F。好了,知道了原理,随机生成中文汉字的程序也就出来了,以下就是生成4个随机汉字的C#控制台代码:3、程序代码:using System;using System.Text;namespace ConsoleApplicationclass ChineseCodepublic static void Main()/获取GB2312编码页(表)Encoding gb=Encoding.GetEncoding(gb2312);/调用函数产生4个随机中文汉字编码object bytes=CreateRegionCode(4);/根据汉字编码的字
26、节数组解码出中文汉字string str1=gb.GetString(byte)Convert.ChangeType(bytes0,typeof(byte);string str2=gb.GetString(byte)Convert.ChangeType(bytes1,typeof(byte);string str3=gb.GetString(byte)Convert.ChangeType(bytes2,typeof(byte);string str4=gb.GetString(byte)Convert.ChangeType(bytes3,typeof(byte);/输出的控制台Console
27、.WriteLine(str1+str2+str3+str4);public static object CreateRegionCode(int strlength)/定义一个字符串数组储存汉字编码的组成元素string rBase=new String160,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f;Random rnd=new Random();/定义一个object数组用来object bytes=new objectstrlength;for(int i=0;i/区位码第1位int r1=rnd.Next(11,14);string str_r1=rBaser1.T
28、rim();/区位码第2位rnd=new Random(r1*unchecked(int)DateTime.Now.Ticks)+i);/更换随机数发生器的种子避免产生重复值int r2;if(r1=13)r2=rnd.Next(0,7);elser2=rnd.Next(0,16);string str_r2=rBaser2.Trim();/区位码第3位rnd=new Random(r2*unchecked(int)DateTime.Now.Ticks)+i);int r3=rnd.Next(10,16);string str_r3=rBaser3.Trim();/区位码第4位rnd=new
29、Random(r3*unchecked(int)DateTime.Now.Ticks)+i);int r4;if(r3=10)r4=rnd.Next(1,16);else if(r3=15)r4=rnd.Next(0,15);elser4=rnd.Next(0,16);string str_r4=rBaser4.Trim();/定义两个字节变量存储产生的随机汉字区位码byte byte1=Convert.ToByte(str_r1+str_r2,16);byte byte2=Convert.ToByte(str_r3+str_r4,16);/将两个字节变量存储在字节数组中byte str_r=
30、new bytebyte1,byte2;/将产生的一个汉字的字节数组放入object数组中bytes.SetValue(str_r,i);return bytes;实现了随机生成汉字后,就可以使用.NET GDI来绘制自己需要的验证码图形了。具体的怎样生成验证码图片,以及改变其中字符的长和宽等效果网上已经有很多相关的文章,这里由于篇幅就不再介绍了。不过有一点要说明的是以上代码在中文版的Windows下才能运行,因为它带有GB的字符集,如果你是其他语言的操作系统,就需要安装GB字符集了。有什么问题可以到发表看法。用.NET获取汉字的区位码(C#)首先复习一下计算机基础知识:计算机中最底层的数据都
31、是用二进制及0和1来表示的。每个0或1称作1位,第8位二进制数叫做1个字节,它可以表示ASCII码中的一个字符。中文计算机中用两个字节即16位二进制来表示一个汉字。而在Unicode编码中所有的符号(包括汉字,英文,标题及其它众多符号)都是为两字节(16)位来表示。在System.Text命名空间中包含众多编码的类,可供进行操作及转换,下面用两个实例来进行区位码及汉字之间的互换,希望能起到举一反三的效果,让大家可以轻松处理文字编码方面的问题:程序代码:using System;using System.Text;class CodingChangepublic string Character
32、ToCoding(string character)string coding=;for(int i=0;ibyte bytes=System.Text.Encoding.Unicode.GetBytes(character.Substring(i,1);/取出二进制编码内容string lowCode=System.Convert.ToString(bytes0,16);/取出低字节编码内容(两位16进制)if(lowCode.Length=1)lowCode=0+lowCode;string hightCode=System.Convert.ToString(bytes1,16);/取出高
33、字节编码内容(两位16进制)if(hightCode.Length=1)hightCode=0+hightCode;coding+=(lowCode+hightCode);/加入到字符串中,return coding;public string CodingToCharacter(string coding)string characters=;转自:作者Blog:进制、8进制、10进制、16进制.各种进制间的轻松转换(c#)在.NET Framework中,System.Convert类中提供了较为全面的各种类型、数值之间的转换功能。其中的两个方法可以轻松的实现各种进制的数值间的转换:Con
34、vert.ToInt32(string value,int fromBase):可以把不同进制数值的字符串转换为数字,其中fromBase参数为进制的格式,只能是2、8、10及16:如Convert.ToInt32(0010,2)执行的结果为2;Convert.ToString(int value,int toBase):可以把一个数字转换为不同进制数值的字符串格式,其中toBase参数为进制的格式,只能是2、8、10及16:如Convert.ToString(2,2)执行的结果为0010现在我们做一个方法实现各种进制间的字符串自由转换:选把它转成数值型,然后再转成相应的进制的字符串:publ
35、ic string ConvertString(string value,int fromBase,int toBase)int intValue=Convert.ToInt32(value,fromBase);return Convert.ToString(intValue,toBase);其中fromBase为原来的格式toBase为将要转换成的格式yolle原作进制转换电脑上的常用进制有:2、8、10、16四种,在修改中经常接触的是2、10和16进制,基本上需要了解的是2和16互转、10和16互转,其他多了解也没亏2转16:4个2进制位为一个16进制数,2进制1111为16进制F,2进制
36、中千位的1=8,百位的1=4,十位的1=2,个位的1=1,将各个位的数作相应转换再相加,的到的数就是10进制数0-15,可轻松转换成16进制。如01011100,可看成是两组2进制数0101和1100,则这个数就是16进制的5C。10转16:100以内一点的10转16心算比较快,复杂的用计算器算了。10转16用传统的计算方式可以了,就是大于15小于256的10进制数除以16为的值为十位的16进制数,其余数为个位的16进制数,没余数则个位为0。如61的16进制是3D,61除以16得3余13,3作十位数,13转成D为各位数。16转10:用相反的道理,将十位数乘以16加上个位数。如5A,将5乘以16
37、得80,加上A的10进制10,结果是90。最直接方便的方法是用windows或win95中的计算器,打开计算器,将计算器置成科学型(win95的乘法),选中十进制选择钮,输入十进制数然后选择二进制选择钮,OK!又快又准确。可是如果你想成为一个合格的程序员的话,你就必须充分了解十进制数和二进制数的特点,最好的方法是你多做一些进制转换的题目,这是程序员训练中的传统做法。三、以十六进制作桥梁十进制到二进制的转换实在麻烦,而且二进制数实在不易记忆和理解,你能马上感觉到一万元是多少钱,但是你能感觉到10011100010000(二进制)是多少吗?为了编程和使用方便,在二进制和十进制之间有了一座桥梁十六进
38、制。十六进制是逢十六进一,0、1、2、3、4、5、9、A、B、C、D、E、F、10、11、12。到了9以后用ABCDEF表示,十六进制数与二进制数的转换非常方便。首先你应当牢记下表二进制十六进制0 01 110 211 3100 4101 5110 6111 71000 81001 91010 A1011 B1100 C1101 D1110 E1111 F二进制数转换成十六进制数方法如下,以二进制数1101110为例:将二进制数从右面开始以四位为一组分组,最左面不够四位的补0,按上表查得对应的十六进制数,组合起来以后就成了。0110 1110的十六进制数是6E十六进制转换成二进制方法如下,以十
39、六进制数3E为例:将十六进制的每一位转换成四位二进制数,不足四位的在左面补0,组合起来即可得到二进制数。3E的二进制数是00111110,既是111110当然你也可以用计算器得出结果。但也建议你熟练掌握。Unicode简介关键词:字库,unicode,big5 Unicode是一种字符编码规范。先从ASCII说起。ASCII是用来表示英文字符的一种编码规范,每个ASCII字符占用1个字节(8bits)因此,ASCII编码可以表示的最大字符数是256,其实英文字符并没有那么多,一般只用前128个(最高位为0),其中包括了控制字符、数字、大小写字母和其他一些符号。而最高位为1的另128个字符被成为
40、扩展ASCII,一般用来存放英文的制表符、部分音标字符等等的一些其他符号这种字符编码规范显然用来处理英文没有什么问题。(实际上也可以用来处理法文、德文等一些其他的西欧字符,但是不能和英文通用),但是面对中文、阿拉伯文之类复杂的文字,255个字符显然不够用于是,各个国家纷纷制定了自己的文字编码规范,其中中文的文字编码规范叫做GB2312-80,它是和ASCII兼容的一种编码规范,其实就是利用扩展ASCII没有真正标准化这一点,把一个中文字符用两个扩展ASCII字符来表示。但是这个方法有问题,最大的问题就是,中文文字没有真正属于自己的编码,因为扩展ASCII码虽然没有真正的标准化,但是PC里的AS
41、CII码还是有一个事实标准的(存放着英文制表符),所以很多软件利用这些符号来画表格。这样的软件用到中文系统中,这些表格符就会被误认作中文字,破坏版面。而且,统计中英文混合字符串中的字数,也是比较复杂的,我们必须判断一个ASCII码是否扩展,以及它的下一个ASCII是否扩展,然后才猜那可能是一个中文字。总之当时处理中文是很痛苦的。而更痛苦的是GB2312是国家标准,台湾当时有一个Big5编码标准,很多编码和GB是相同的,所以,嘿嘿。这时候,我们就知道,要真正解决中文问题,不能从扩展ASCII的角度入手,也不能仅靠中国一家来解决。而必须有一个全新的编码系统,这个系统要可以将中文、英文、法文、德文等
42、等所有的文字统一起来考虑,为每个文字都分配一个单独的编码,这样才不会有上面那种现象出现。于是,Unicode诞生了。Unicode有两套标准,一套叫UCS-2(Unicode-16),用2个字节为字符编码,另一套叫UCS-4(Unicode-32),用4个字节为字符编码。以目前常用的UCS-2为例,它可以表示的字符数为216=65535,基本上可以容纳所有的欧美字符和绝大部分的亚洲字符。UTF-8的问题后面会提到。在Unicode里,所有的字符被一视同仁。汉字不再使用两个扩展ASCII,而是使用1个Unicode,注意,现在的汉字是一个字符了,于是,拆字、统计字数这些问题也就自然而然的解决了。
43、但是,这个世界不是理想的,不可能在一夜之间所有的系统都使用Unicode来处理字符,所以Unicode在诞生之日,就必须考虑一个严峻的问题:和ASCII字符集之间的不兼容问题。我们知道,ASCII字符是单个字节的,比如A的ASCII是65。而Unicode是双字节的,比如A的Unicode是0065,这就造成了一个非常大的问题:以前处理ASCII的那套机制不能被用来处理Unicode了。另一个更加严重的问题是,C语言使用message作为字符串结尾,而Unicode里恰恰有很多字符都有一个字节为0,这样一来,C语言的字符串函数将无法正常处理Unicode,除非把世界上所有用C写的程序以及他们所
44、用的函数库全部换掉。于是,比Unicode更伟大的东东诞生了,之所以说它更伟大是因为它让Unicode不再存在于纸上,而是真实的存在于我们大家的电脑中。那就是:UTF。UTF=UCS Transformation Format UCS转换格式它是将Unicode编码规则和计算机的实际编码对应起来的一个规则。现在流行的UTF有2种:UTF-8和UTF-16。其中UTF-16和上面提到的Unicode本身的编码规范是一致的,这里不多说了。而UTF-8不同,它定义了一种区间规则,这种规则可以和ASCII编码保持最大程度的兼容。UTF-8有点类似于Haffman编码,它将Unicode编码为00000
45、000-0000007 F的字符,用单个字节来表示;00000080-000007 FF的字符用两个字节表示00000800-0000FFFF的字符用3字节表示因为目前为止Unicode-16规范没有指定FFFF以上的字符,所以UTF-8最多是使用3个字节来表示一个字符。但理论上来说,UTF-8最多需要用6字节表示一个字符。在UTF-8里,英文字符仍然跟ASCII编码一样,因此原先的函数库可以继续使用。而中文的编码范围是在0080-07FF之间,因此是2个字节表示(但这两个字节和GB编码的两个字节是不同的),用专门的Unicode处理类可以对UTF编码进行处理。下面说说中文的问题。由于历史的原
46、因,在Unicode之前,一共存在过3套中文编码标准。GB2312-80,是中国大陆使用的国家标准,其中一共编码了6763个常用简体汉字。Big5,是台湾使用的编码标准,编码了台湾使用的繁体汉字,大概有8千多个。HKSCS,是中国香港使用的编码标准,字体也是繁体,但跟Big5有所不同。这3套编码标准都采用了两个扩展ASCII的方法,因此,几套编码互不兼容,而且编码区间也各有不同因为其不兼容性,在同一个系统中同时显示GB和Big5基本上是不可能的。当时的南极星、RichWin等等软件,在自动识别中文编码、自动显示正确编码方面都做了很多努力。他们用了怎样的技术我就不得而知了,我知道好像南极星曾经以同屏显示繁简中文为卖点。后来,由于各方面的原因,国际上又制定了针对中文的统一字符集GBK和GB18030,其中GBK已经在Windows、Linux等多种操作系统中被实现。GBK兼容GB2312,并增加了大量不常用汉字,还加入了几乎所有的Big5中的繁体汉字。但是GBK中的繁体汉字和Big5中的几乎不兼容。GB18030