GB2312编码(为什么要加2020H、8080H,外码→内码→交换码→字形码)

摘要:
为什么要加上2020H和8080H?其实我们说国标码才是GB2312的规范编码,后来的内码是微软为了解决冲突问题而采用的方式,本质上是修改了GB2312的编码标准,而这种方法最后产生的编码最后就被一些教科书称为内码你需要先了解汉字的输入、存储、交换与显示过程:外码→内码→交换码→字形码。

为什么要加上2020H和8080H?

区位码、内码、国标码怎么转换非常简单,但是令人迷惑的是为什么要那么转换?这种转换不可能平白无故地那样转换!

我搜索很多资料,找到最好的解释,总结如下:

首先,注意到一点,GB2312虽说是对中文编码,但是里面有对26个英文字母和一些特殊符号的编码,按理说这和ASCII重合的部分应该无需设置,沿用ASCII中不就行了?但是当时在制定GB2312之前,就决定覆盖掉ASCII中符号和英文字母部分,所以将其中的英文字母和符号重新编入GB2312中。而对于ASCII中前32个控制字符则继续沿用。所以保留前32字符,就需要将汉字编码向后偏移32,十六进制20H,这也就是区位码要加上20H得到国标码,这就是GB2312的编码规范。

而这样产生一个弊端,某些早期用ASCII码编码的英文文章无法打开,一打开就是乱码,也就是说应该要兼容早期ASCII码而不是覆盖它!为了解决这个问题,将字节的最高位设为1,因为ASCII中使用7位,最高位为0。这样就区分开了ASCII和GB2312。这也是为什么要加上8080H。 其实我们说国标码才是GB2312的规范编码,后来的内码是微软为了解决冲突问题而采用的方式,本质上是修改了GB2312的编码标准,而这种方法最后产生的编码最后就被一些教科书称为内码

扩展

你需要先了解汉字的输入、存储、交换与显示过程:外码→内码→交换码→字形码。
外码:又称输入码,我们平常用的拼音输入和五笔输入法所敲打的字母。
内码:计算机存储信息是二进制的,输入的汉字要转化成二进制的形式,它们的集合就叫字符集。
交换码:又称国标码,是和别的计算机交换信息时使用的编码。
字形码:又称汉字字模,把二进制的汉字编码还原为可视的图形,它们的集合又叫字库。

下面说英文与汉字处理的区别:

1、外码
英文的字母只有26个,可以直接用键盘表示,直接通过译码电路转换为内码,但有些国家的拼音字母不止26个,要么制作一个特殊的键盘,要么和汉字那样的输入一串符号来表示一个字符,这一串符号就叫输入码。
2、内码
先说拼音字母,同样的理由,英文字母只有26个,加上大小写的区别,数字,标点,再加上一些特殊符号,如空白、回车等,很容易构成一个有128个字符的单字节存储的ASCII字符集,这个是美国的标准,还有IBM自己的标准EBDIC字符集,这样同一个二进制数还原成字符就至少有两种可能,比如二进制数01001110,在ASCII中代表大写字母N,在EBCDIC中却是加号+。

ASCII编码在运用中是以字节(8位)来处理的,实际上用7位二进制数就可以表示出128个符号,最高位都是以0填充的,但是只用掉7位来表示不是浪费么?比如有些国家不止26个字母,需要增加。货币符号也不一样,比如英镑£。最高位是1的话,一个字节就可以再表示128个符号,总计256个符号。然后就有不同的计算机厂商扩展了ASCII,这个扩展的字符集就没有统一的标准了,这样就会带来一个问题,在第128个基础字符之后的字符,同样的二进制代码,怎么还原成正确的字符?

汉字有好几万个,单字节可编不完,但常用的就那么几千个,所以最初就有GB2312这个双字节存储的字符集,理论上可以存储16384(128*128)个字符,但后来计算机存储容量增加了,不用吝啬那点存储空间,就扩展了字符集,把繁体字啊,少数民族的字啊都加进去,形成了1~4个字节表示的GB18030字符集。港澳台还有自己的繁体字字符集,如Big5。这同样造成了识别问题。
这三个问题的解决方法是内码表,又称代码页(Code Page),给不同国家的语言加个编码来区分,如37是IBM EBCDIC(US-Canada),936是简体中文GBK,950是繁体中文Big5,1253是希腊文。这个东西可以在Windows XP的“控制面板→区域和语言选项→高级”中查看。过去玩繁体中文版的游戏,直接打开就是乱码,最直接的解决方法就是换成繁体版的操作系统来玩,但更多的时候我们是用内码转换器使游戏正常显示,比如微软官方的Microsoft AppLocale Utility软件。
补充说明:
GB2312没有使用全部的128×128=16384个字符,实际只有94×94=8836个字符可用最终用到了7445个。

3、交换码
GB2312-80的全称是《中华人民共和国 国家标准 信息交换用汉字编码字符集 基本集》,本标准规定了汉字信息交换用的基本图形字符及其二进制编码表示。它适用于一般汉字处理、汉字通信等系统之间的信息交换。它把图形字符的代码表分为94个区,每个区有94位。区的编号从1~94,由第一字节标识;位的编号也是从1~94,由第二字节标识。例如汉字“啊”用16—01表示(十进制,16进制:10H,01H),这个编码称为区位码,二进制表示为00010000 00000001。

前面讲了ASCII和GB2312两个字符集,其中GB2312为了兼容ASCII也是使用两个字节中的低7位来编码,这样会在传输时出现一个问题,ASCII从00000000到00011111这前32个字符是控制符,比如00000100是在ASCII中是控制符EOT,意思是传输结束,而在GB2312的区位码中只是表示区号04或者位号04,传输中可是没有代码页来识别你是ASCII还是GB2312,所以为了不发生冲突,在进行信息交换时在区号和位号上都加32这样就防止了冲突,加上了32以后的编码就称为交换码。还是用汉字“啊”举例,区号16+32=48,二进制为00110000,位号01+32=33,二进制为00100001,合起来“啊”的交换码就是00110000 00100001。

上面讲内码时说到个识别问题,单独的英文或者中文都好解决,但如果是一篇使用半角输入的中英混合的文章怎么办?比如刚刚所举的例子,交换码00110000 00100001除了可以表示汉字“啊”,也可以表示为ASCII字符中的“0”和“!”。计算机如何识别哪个字节该用ASCII,哪个字节该用GB2312呢?所以为了以示区分,在GB2312空着的最高位置1,于是“啊”的交换码就变为了内码10110000 10100001,换成十六进制就是B0 A1,大家可以找份GB2312的内码对照表来看看是不是这样。

补充说明:
半角和全角输入的拼音字母的二进制码是不一样的,比如半角输入的字母A,二进制码是01000001,十六进制是41,这是按ASCII字符集编码的,而全角输入的字母A,二进制编码是10100011 11000001,十六进制是A3 C1,这是按GB2312字符集编码的。

4、字形码
这个举个例子就明白了,比如“口”字,画成8×8的点阵图就是:
00000000
01111110
01000010
01000010
01000010
01000010
01111110
00000000
这样一个“口”字需要8个字节来存储。当然这只是其中一种最简单的表示方法,常用的还有16×16、24×24和32×32等点阵字形编码。而且同一个字还有不同字体的写法,如宋体、隶书和黑体等。同一种字体除了用点阵表示,还可以用矢量来表示,比如Windows中使用的TrueType字体。

免责声明:文章转载自《GB2312编码(为什么要加2020H、8080H,外码→内码→交换码→字形码)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Python 用SMTP发送邮件Android中的数据存储下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

搞懂js中小数运算精度问题原因及解决办法

js小数运算会出现精度问题 js number类型 JS 数字类型只有number类型,number类型相当于其他强类型语言中的double类型(双精度浮点型),不区分浮点型和整数型。 number类型不同进制 number 有四种进制表示方法,十进制,二进制,八进制和十六进制 表示方法 二进制: 0B或者0b (数字0和字母B或者小写字母b) ,后接...

winCE下Unicode编码

Unicode :宽字节字符集 1. 如何取得一个既包含单字节字符又包含双字节字符的字符串的字符个数? 可以调用Microsoft Visual C++的运行期库包含函数_mbslen来操作多字节(既包括单字节也包括双字节)字符串。 调用strlen函数,无法真正了解字符串中究竟有多少字符,它只能告诉你到达结尾的0之前有多少个字节。 2. 如何...

Unity资源Assetbundle

转  Unity资源打包之Assetbundle 本文原创版权归 csdn janeky 所有,转载请详细注明原创作者及出处,以示尊重! 作者:janeky 原文:http://blog.csdn.net/janeky/article/details/17652021 如果这篇文章对你有帮助,敬请关注作者《Unity手游之路》系列教程。 在手游的运营过程中...

任意给定一个正整数N,求一个最小的正整数M(M>1),使得N*M的十进制表示形式里只含有1和0。

题目:任意给定一个正整数N,求一个最小的正整数M(M>1),使得N*M的十进制表示形式里只含有1和0。 解法一:暴力求解。从1开始查找M,然后判断M*N=X这个数字是否只含有0,1. 解法二:由于没有直接的数学方法能帮我们直接得到M的值,所以我们只能进行搜索。由于相对M,乘积N*M具有明显的特征,需要搜索的空间要小很多,所以我们对乘积N*M进行搜...

什么是哈希

什么是哈希   把任意长度的输入通过散列算法变换成固定长度的输出,称为哈希(hash),又称散列 为什么是哈希不可逆 就像1+4=5和2+3=5一样,你现在知道我的结果是5,能知道我输入的什么数字吗? 哈希算法的概念和特性 我们前面分享了散列表、散列函数和散列冲突,其实也可以译作哈希表、哈希函数和哈希冲突,是一个意思。哈希算法简单理解就是实现前面提到的哈...

c语言运算符

1.运算符概述 运算符是一种编译器执行特定的数学或逻辑操作的符号。C语言提供了以下类型的运算符: 算术运算符 关系运算符 逻辑运算符 位运算符 赋值运算符 条件运算符 其他运算符 2.算术运算符 算术运算符分为单目运算符和双目运算符,单目运算符表示只需要一个操作数,双目运算符需要两个操作数。 2.1 双目算术运算符 1)+ :加法,把两个操作数相加...