字符的编码格式

5、字符的编码格式

讲到字符的编码格式,已经接触到这么几个名词:ANSI、OEM、DBCS、Unicode、国标码、GBK、机内码、区位码,分别是什么含义呢?百度一下

ANSI , 这是美国国家标准协会制定的编码格式,例如"A汉" 在这种编码方式下的内存值为 41 BA BA ,'A'占用一个字节,"汉"用两个字节,记事本里用的好像就是ANSI编码。所以,ANSI = ASCII + 本地编码

GB2312,GBK,GB18030都是中国人自己发明的(中国之外并不使用的), 他们出现的时间顺序是GB2312-> GBK -> GB18030 ,他们是包含关系,GB我猜是 "国标" 的意思 "k" 可能是"扩展", 这些编码都是书面协议,要在计算机内部表示。所以GB2312的内存值须在原来的每个字节值(区位码)上加0x80得到机内码,加上0x80是为了使得每个字节的最高位为1,这样就可以在内存中区分汉字和ASCII了[因为ASCII的最高位都为0]. 但是后来要在GB2312上扩展(得到GBK,GB18030),就需要更多的编码空间,所以GBK,GB18030就没有要求第二个字节的的最高位为1了,而是通过第一个字节来判断这是一个字节的ASCII还是两个字节的GBK.GB2312、GBK都属于双字节字符集 (DBCS)。

所有的国标码汉字及符号组成一个94行94列的二维代码表中。在此方阵中,每一行称为一个"区",每一列称为一个"位"。这个方阵实际上组成一个有94个区(编号由01到94),每个区有94个位(编号由01到94)的汉字字符集。每两个字节分别用两位十进制编码,前字节的编码称为区码,后字节的编码称为位码,此即区位码,其中,高两位为区号,低两位为位号。

区位码  国标(GBK)  内码

"汉" 1A1A    3A3A      BABA

国标 = 区位码 + 0x20 (每个字节)

内码 = 国标(GBK) + 0x80 (每个字节)

目前Windows的内核已经支持Unicode字符集,这样在内核上可以支持全世界所有的语言文字。但是由于现有的大量程序和文档都采用了某种特定语言的编码,例如GBK,Windows不可能不支持现有的编码,而全部用Unicode。Windows使用代码页(codepage)来适应各个国家和地区。codepage可以被理解为前面提到的内码。GBK对应的codepage是CP936。

输入码就是使用英文键盘输入汉字时的编码。目前,我国已推出的输入码有数百种,但用户使用较多的约为十几种,按输入码编码的主要依据,大体可分为顺序码、音码、形码、音形码四类,如“保”字,用全拼,输入码为码为“BAO”,用区位码,输入码为“1703”,用五笔字型则为“WKS”。

“这是一个长文件名.txt”文件在14号簇,2072扇区,读出来如下:

CE D2 B5 C4 D0 C4 D6 D0 D3 D0 D2 BB B8 F6 C3 CE CF EB A1 A3

61 62 63 64 65 66 67 2C 31 32 33 34 35 36 37 2E 00 00 00 00,abcdefg和1234567是我后面修改后加的,说明这个编码不是unicode编码。因为汉字两个、英文一个编码,这应该就是acii码加上汉字国标机内码。

汉字我的编码是: CE D2减去80 80 后得到4e 52,应该是国标码,减去20 20 得到2E 32就是区位码。而我的unicode码是0x62 11=25105。若果造一个内码-unicode码转换表,应该是在第46区 50位。

2312转Unicode:

基于区位码计算编码库偏移地址,这个大家都做过,编码库的字节大小为2倍2312字库,库里只存Unicode码

Unicode转2312:

建立64K编码库(128K 字节,库里只存2312码, 不存在2312码的用0x0000补齐),用Unicode码的值做偏移地址直接查找对应的2312码,不用计算

中文字库就比较麻烦了。先取得汉字的内码,如使用GBK,‘上’的内码是0xc9,0xcf。在查到在对应字库中位置。取得该汉字的字库。

一般字库文件是按照GB 2312-80标准,也就是通常所说的国标码或区位码的标准排列的。国标码分为 94 个区(Section),每个区 94 个位(Position),所以也称为区位码。其中01~09 区为符号、数字区,16~87 区为汉字区。而 10~15 区、88~94 区是空白区域。如何取得汉字的区位码呢?在计算机处理汉字和ASCII字符时,使每个ASCII字符占用1个字节,而一个汉字占用两个字节,其值称为汉字的内码。其中第一个字节的值为区号加上32(20H),第二个字节的值为位号加上32(20H)。为了与ASCII字符区别开,表示汉字的两个字节的最高位都是1,也就是两个字节的值都又加上了128(80H)。这样,通过汉字的内码,就可以计算出汉字的区位码。具体算式如下:qh="c1-32-128"=c1-160 wh="c2-32-128"=c2-160 或qh="c1-0xa0" wh="c2-0xa0" qh,wh为汉字的区号和位号,c1,c2为汉字的第一字节和第二字节。根据区号和位号可以得到汉字字模在文件中的位置:location=(94*(qh-1)+(wh-1))*一个点阵字模的字节数。

 

5、有关字符编码的最后总结

上面有关编码的内容都是在百度上搜到的,我把重点标示了出来。我的收获是对于汉字在机内存储和如何显示的原理有了简单的了解。

我们在用输入法输入汉字的时候,看到了“真正的字”,但实际文件中一般只是存储的汉字内码。它如何让我们看到的呢?通过简单的转换得到区位码,区位码实际上指出了该汉字在字库文件中字符点阵储位置。通过获取点阵,在屏幕上显示汉字。

有时候,汉字在内部以unicode码的格式存储,比如文件系统中长文件名,都是这样。那我们要操作文件系统,怎么样才能由内码得到unicode码呢?这个可以用一张转换表来实现,这张表可以以汉字区位表为基础,共需要94*94*2这么大,大概20K左右。

如果要显示文件系统中汉字命名的文件,需要先由unicode码得到内码,然后再获取字型数据显示,这时也可以用一张表,但这个表稍微大一些,因为unicode有65536个,这张表需要128k大。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值