免费网站怎么样,安徽建设工程信息网安管人员查询,12306网站是阿里做的,5星做号宿水软件的网站GB2312、GBK、GB18030等GB系列汉字编码方案的具体实现方式是怎样的#xff1f;区位码是什么#xff1f;国标码是什么#xff1f;内码、外码、字形码又是什么意思#xff1f;它们是如何转换的#xff0c;又为什么要这样转换#xff1f;
下面以GB2312为例来加以说明。 一、…GB2312、GBK、GB18030等GB系列汉字编码方案的具体实现方式是怎样的区位码是什么国标码是什么内码、外码、字形码又是什么意思它们是如何转换的又为什么要这样转换
下面以GB2312为例来加以说明。 一、区位码
1.
整个GB2312字符集分成94个区每区有94个位每个区位上只有一个字符即每区含有94个汉字或符号用所在的区和位来对字符进行编码(实际上就是码点值、码点编号、字符编号)因此称为区位码(或许叫“区位号”更为恰当)。
换言之GB2312将包括汉字在内的所有字符编入一个94*94的二维表行就是“区”、列就是“位”每个字符由区、位唯一定位其对应的区、位编号合并就是区位码。
比如“万”字在45区82位所以“万”字的区位码是45 82注意GB类汉字编码为双字节编码因此45相当于高位字节82相当于低位字节。
2.
GB2312字符集中
101~09区(682个)特殊符号、数字、英文字符、制表符等包括拉丁字母、希腊字母、日文平假名及片假名字母、俄语西里尔字母等在内的682个全角字符
210~15区空区留待扩展
316~55区(3755个)常用汉字(也称一级汉字)按拼音排序
456~87区(3008个)非常用汉字(也称二级汉字)按部首/笔画排序
588~94区空区留待扩展。 二、国标码(交换码)
1.
为了避开ASCII字符中的不可显示字符0000 0000 ~ 0001 1111(十六进制为0 ~ 1F十进制为0 ~ 31)及空格字符0010 0000(十六进制为20十进制为32)至于为什么要避开、又为什么只避开ASCII中0~32的不可显示字符和空格字符后文有解释国标码(又称为交换码)规定表示汉字的范围为(0010 00010010 0001) ~ (0111 11100111 1110)十六进制为(2121) ~ (7E7E)十进制为(3333) ~ (126126)。
因此必须将“区码”和“位码”分别加上32(十六进制为20可写作20H或0x20后缀H或前缀0x都可表示十六进制)作为国标码。也就是说国标码相当于将区位码向后偏移了32以避免与ASCII字符中0~32的不可显示字符和空格字符相冲突。
2.
注意国标码中是分别将区位码中的“区”和“位”各自加上32(20H)的因为GB2312是DBCS双字节字符集因此国标码属于双字节码。
这样我们可以算出“万”字的国标码十进制为(45328232) (77114)十六进制为(4D72)二进制为(0100 11010111 0010)。
笨笨阿林原创文章转载请注明出处 三、内码(机内码)
1.
不过国标码还不能直接在计算机上使用因为这样还是会和早已通用的ASCII码冲突从而导致乱码。
比如“万”字国标码中的高位字节77与ASCII的“M”冲突低位字节114与ASCII的“r”冲突。因此为避免与ASCII码冲突规定国标码中的每个字节的最高位都从0换成1即相当于每个字节都再加上128(十六进制为80即80H二进制为1000 0000)从而得到国标码的“机内码”表示简称“内码”。
2.
由于ASCII码只用了一个字节中的低7位所以这个首位(最高位)上的“1”就可以作为识别汉字编码的标志计算机在处理到首位是“1”的编码时就把它理解为汉字在处理到首位是“0”的编码时就把它理解为ASCII字符。
比如 77 128 205(二进制为1100 1101十六进制为CD) 114 128 242(二进制为1111 0010十六进制为F2)
3.
我们可以来检验一下。打开记事本输入“万”字编码选择为ANSI(Windows记事本中的ANSI编码在简体中文版操作系统中默认为GB类编码详见后文解释)保存如下图所示。 然后用二进制编辑器(比如UltraEdit)打开刚才保存的文件切换到十六进制模式会看到CD F2这就是“万”字的内码如下图所示。 4.
小结一下
从区位码(国家标准定义) --- 区码和位码分别32(即20H)得到国标码 --- 再分别128(即80H)得到机内码(与ACSII码不再冲突)。
因此区位码的区和位分别160(即A0H32128160)可直接得到内码。用十六进制表示就是 区位码(区码, 位码) (20H, 20H) (80H, 80H) 区位码(区码, 位码) (A0H, A0H) 内码(高字节, 低字节)。 注十六进制数既可通过添加后缀H来表示也可通过添加前缀0x来表示 四、为什么要加上20H和80H
1.
区位码、国标码、内码的转换非常简单但令人迷惑的是为什么要这么转换
首先需要注意到一点GB2312虽说是汉字编码方案但其实里面也有针对26个英文字母和一些特殊符号的编码按理说这些和ASCII重合的字符(33~127)应该无需再重新编码直接沿用ASCII编码不就行了
2.
原来当时在制定GB2312时决定对ASCII中的可打印字符也就是英文字母、数字和符号部分(33~126127为不可打印的DEL)重新编入GB2312中以两个字节表示称之为全角字符(全角字符在屏幕上的显示宽度为ASCII字符的两倍后来也因此而将对应的ASCII字符称之为半角字符)。
而对于ASCII中前32个不可显示也不可打印的控制字符(ASCII码为0~31)以及第33个可显示但不可打印的空格字符(ASCII码为32)等一共33个不可打印字符的编码则直接沿用不再重新编码。
3.
因为要保留这33个不可打印字符就不能直接采用区位码作为计算机直接处理的机内码需要将区位码向后偏移32以避开冲突(为什么是偏移32而不是偏移33因为区位码中的区码和位码都是从1开始计数的不像ASCII码是从0开始计数的)。
十进制数字32的十六进制表示就是20H这也就是区位码的区码和位码都分别要加上20H才能得到国标码的原因。
笨笨阿林原创文章转载请注明出处
4.
不过如果直接采用国标码作为计算机直接处理的机内码的话还是会与SCII编码产生冲突导致乱码。
因为国标码虽然相较于区位码避开了ASCII码中0~32的前33个不可打印字符但并没有避开ASCII码中的英文字母、数字和符号等可打印字符(33~126共94个字符)以及不可打印的DEL(127)。也就是说国标码并不是完全兼容ASCII码的。
5.
为了彻底避免与ASCII码的冲突考虑到ASCII码只使用了一个字节中的低7位其最高位(即首位)总是为0于是决定将国标码中每个字节的最高位设为1(国标码的两个字节中的最高位都总是为0即国标码中的每个字节与ASCII码一样实际上也只用了一个字节中的低7位)这就是GB2312的机内码(即内码)简称GB2312码。
这样一来就彻底区分开了ASCII码和GB2312码。这也是为什么国标码还要加上(80H80H)才能得到机内码的原因。
6.
看到这里有人或许又要问了如果仅仅是为了避免与ASCII码相冲突为什么最初不直接将区位码的区码和位码的最高位从0改为1(相当于各自直接加上128)这样不就无需经过国标码多此一举的中间转换了吗而且还无需后移32也就不用浪费这部分编码空间。
对此本人也很困惑在网上搜了很久也没找到答案因此具体原因不得而知。或许是一开始考虑不周或许是为了未来扩展所需而预留一部分空间又或许是有其他不得已的原因有知道的朋友还望能指点迷津。 GB2312区位码、国标码、内码对照表(其中汉字内码B0A1~F7FE共6763个) 五、外码(输入码、输入法编码)
1.
外码也叫输入码、输入法编码是用来将汉字输入到计算机中的一组键盘符号是作为汉字输入用的编码。
英文字母只有26个可以把所有的字符都放到键盘上而使用这种办法把所有的汉字都放到键盘上是不可能的。所以汉字系统需要有自己的输入码体系使汉字与键盘能建立起对应关系。
2.
目前常用的汉字外码分为以下几类
1数字编码比如区位码
2拼音编码比如全拼、双拼、自然码等
3字形编码比如五笔、表形码、郑码等。
3.
汉字外码往往会出现重码。
所谓重码指的是同一个汉字外码对应于多个汉字反过来说也就是可能有多个汉字的外码是相同的相当于重复了所以称之为“重码”。比如使用拼音作为外码时(即使用拼音输入法输入汉字时)重码现象是相当普遍的。
当出现重码时往往需要附加选择编号以具体确定所要输入的汉字这种情况下可认为外码实际上相当于隐式地包括了选择编号在内。 六、字形码(字型码、字模码、输出码)
1.
字形码又称为字型码、字模码、输出码属于点阵代码的一种。
为了将汉字在显示器或打印机上输出把汉字按图形符号设计成点阵图就得到了相应的点阵代码(字形码)。
也就是用0、1表示汉字的字形将汉字放入n行*n列的正方形(即点阵)内该正方形共有n^2个小方格每个小方格用一位二进制数表示凡是笔划经过的方格其值为1未经过的方格其值为0。
2.
显示一个汉字一般采用16×16点阵或24×24点阵或48×48点阵。已知汉字点阵的大小可以计算出存储一个汉字所需占用的字节空间。
比如用16×16点阵表示一个汉字就是将每个汉字用16行每行16个点表示一个点需要1位二进制数16个点需用16位二进制数(即2个字节)所以需要16行×2字节/行32字节即以16×16点阵来表示一个汉字字形码需要32字节。
因此字节数点阵行数×(点阵列数/8)。
3.
显然字形码所表示的字符相对于抽象字符表ACR里的“抽象”字符可称之为“具体”字符因为已经具有了“具体”的外形。 4.
为了将汉字的字形显示输出或打印输出汉字信息处理系统还需要配有汉字字形库也称字模库简称字库它集中存储了汉字的字形信息。
字库按输出方式可分为显示字库和打印字库。用于显示输出的字库叫显示字库工作时需调入内存。用于打印输出的字库叫打印字库工作时无需调入内存。
字库按存储方式也可分为软字库和硬字库。软字库以字体文件(即字形文件)的形式存放在硬盘上现多用这种方式。硬字库则将字库固化在一个单独的存储芯片中再和其它必要的器件组成接口卡插接在计算机上通常称为汉卡。这种方式现已淘汰。 七、总结
1. 可以这样理解为在计算机内表示汉字而采取统一的编码方式所形成的汉字编码叫内码。为方便汉字输入而形成的汉字编码为外码也叫输入码。为显示输出和打印输出汉字而形成的汉字编码为字形码也称为字模码、输出码。
通过键盘输入汉字外码然后输入法将汉字外码转换为当前操作系统所默认采用的字符编码方案的字符编号(即码点值)再根据字符编号通过代码页查表的方式转换为汉字内码(代码页详见前文的介绍)以实现输入汉字的目的然后根据所选择的字体通过汉字内码在字模库(即字库)中找出与字体相对应的字形码从而将汉字内码转换为汉字字形码以实现显示输出和打印输出汉字的目的。 事实上英文字符的输入、处理和显示过程大致上也差不多只不过英文字符不需要输入码(即外码)直接在键盘上输入对应的英文字母即可。
2.
注意ASCII码以及EASCII、ISO 8859系列、GB系列、Big5和Shift JIS等既兼容ASCII码又互相之间不兼容的ANSI编码(“ANSI编码”是对世界上各个国家和地区所制定的既兼容ASCII码又互相之间不兼容的各种字符编码的统称下一篇文章将详细介绍这个统称的来龙去脉)都属于传统字符编码模型而不属于现代字符编码模型很难直接简单套用现代字符编码模型中的概念来表述。
如果一定要套用的话就GB系列编码而言勉强来说区位码相当于现代字符编码模型中编号字符集CCS的字符编号国标码相当于字符编码方式CEF的码元序列而机内码则相当于字符编码模式CES的字节序列。
不过由于GB系列编码虽然是多字节编码但码元却是单字节码元(码元的概念后文有详细介绍)因此不存在字节序问题也就不存在字符编码模式CES中的大端序、小端序的概念(字节序以及大端序、小端序的概念后文有详细介绍)。
笨笨阿林原创文章转载请注明出处 【预告下一篇将重点剖析非常容易令人困惑的所谓ANSI编码与代码页(Code Page)敬请关注】 0x80~0x9f 在ISO 8859中是C1控制字符兼容原因