编码历史
一、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个字节。
那么,对于变长来说,如何确定字符的边界?
也就是说,你怎么确定哪几个字节与特定字符之间的关系。?
比如,23,179,234,123这几个字节,哪几个代表一个字符?
还是如上图,对于最高位的字节,如果有两个1,就是2个字节,三个1,就是3个字节。。。以此类推。
六、乱码的问题
6.1、乱码是怎么形成的?
- 1、解码时,与实际编码不一致。
原因:比如,文本是utf-8,但是偏告诉解码器是GBK,所以就乱码了。
解决办法:碰到这种情况,只需要让编码与解码一致就可以了。 - 2、传输过程中,导致字节丢失,不可修复
比如,对于utf-8的字节(容量比较大),非要转成GB2312(容量比较小)进行传输,导致字节丢失。
解决办法L不可修复
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中如何设置字符集了。