27、GB2312与UTF8编码详解

2018-12-16  本文已影响0人  小碧小琳

编码历史

一、ASCII编码

一开始,美国人发明字符的时候,只考虑了键盘上有的一些字符(英文字母、一些特殊符号)。
也就是ASCII编码。

怎么表示的呢?一共只有不到127个字符,所以一共字节就足以表示了。

ascci 一个字节,第一个比特位为0 ,0-127个字符

但是,比如传到中国,常用汉字就有3000多个,就要扩充字节了。

二、GB3212

最开始,用两个字节,规定两个字节都不占用0-127位的比特位,
也就是说,能用的第一个字节有效值范围为129-255,第二个也是129-255
那么可以表示的字符就多了一些,并且避免跟ASCII混淆。

但是,还有很多偏僻字,特殊字符呢?

再增加字符个数呗。

三、GBK编码

相对于上一个编码,GBK也是两个字节,不过其中第二个字节可以占用0-127位,也就是说,第一个字节范围十进制数是129-255,第二个字节是0-255的。这样理论上就可以表示很多的字符,足够挥霍了。
(而实际上,GBK是第一个字节128-255,第二个字节是65-255的)。

例题:判断编码是GBK还是ASCII。

比如,对于148,35,65,149,66连着的,判断中英文。

GBK中,第一个字节一定是大于128的(一定不是小于128的)。
所以可以判断,148,35是一个中文,65是一个英文,149,66是一个中文。所以上面就是“中文字,字母,中文字”

平时我们看到的ASII编码,代表本地编码。比如,在中国ASII代表的就是GBK编码规则。在日本代表的就是JIS编码。

四、编码规则多,就不兼容了

世界各国的语言不尽相同,那么字符集也就不相同,对于GBK编码好的文档,到日本用JIS去解码,就肯定是乱码了。
也就是兼容性不行。

类似于各国之间的交流,我们需要一个通用的大家都能理解的语言来统一编码,统一解码。于是就有了Unicode编码。

五、Unicode编码

Unicode一共有4个字节,编码有40多亿中方式,足够用了。
unicode是包含了世界所有通用的字符集,每个编码就是一个特定的标号,规定死了。

但是,随之而来也有一个问题,Unicode确实能够解决兼容性问题,但是我们平时用不到那么多字符的啊。比如我们最常用的字符,都集中在前面的65535个字符中。
也就是说可能平时2个字节就够用了。

如果一直用Unicode负责分配编号,用4个字节来分配编号。会存在浪费空间缺点。

于是,有人提出,让Unicode负责编号,用一个规则在不改变Unicode编号的基础上,简化字节。
比如:

上图中,把高位浪费的0值,用一定的规则舍弃,节省了空间。

这种简化方式(也就是规则)有几种,其中最出名的是Unicode转换格式(Unicode Transformation Format,简称为UTF)

在UTF中,比较出名的就是UTF-8.
Unicode与utf-8的关系,就像是原文件与压缩文件的关系。


问1、:给定Unicode字符,能不能得到utf-8的二进制值?
答:肯定能。

问2、:utf-8能反推出Unicode字符吗?
答:能。

二者就是一个编码与解码的关系。

问:utf-8占用几个字节呢?
答:首先,是不可能定长的。(否则没法压缩)。是变长的,1-6个字节。

utf-8与Unicode之间的转换关系

那么,对于变长来说,如何确定字符的边界?
也就是说,你怎么确定哪几个字节与特定字符之间的关系。?

比如,23,179,234,123这几个字节,哪几个代表一个字符?

还是如上图,对于最高位的字节,如果有两个1,就是2个字节,三个1,就是3个字节。。。以此类推。

六、乱码的问题

6.1、乱码是怎么形成的?

6.2、怎么解码utf-8?

那么主要的问题来了,如何截取utf-8(各国语言都有),并且无乱码?
(也就是说,正确的划分23,179,234,123这几个数字,并且没有乱码)

答:从头开始,取第1个字节,通过位运算,计算连续的1的个数。
如为0,则截取第一个字节
如为N,则截取第N个字节


问3:GBK中文,经常在java中,被转为utf-8,是怎么转的?
答:通过Unicode中间转换。(GBK也是和Unicode有关系的,先转成Unicode,再转成utf-8)


铺垫完成,接下来,就是学习在MySQL中如何设置字符集了。

上一篇 下一篇

猜你喜欢

热点阅读