365bet官网中文网-365网站靠谱不-28365365体育在线

Est. 1980 · 每日复古新闻

编码的历史,ASCII,UTF8,UTF32,GB2312,GBK,乱码的原理

编码的历史,ASCII,UTF8,UTF32,GB2312,GBK,乱码的原理

编码的历史,ASCII,UTF8,UTF32,GB2312,GBK,乱码的原理

在很多时候,比如玩游戏的时候,游戏程序会报错,出现乱码,就如我上一个博客里说的玩galgame出现菱形问号乱码,还有被人津津乐道的“锟斤拷”,于是学习整理了一点关于编码的问题。

首先我们先得明白,什么是编码

我们都知道嗷,计算机只能储存0和1这种二进制数字,无论是emoji表情,汉字,英文字母,还是各国语言和标点符号,都是计算机以某种方式将其转换为二进制的一串数字进行储存和读取的。

我们都知道计算机起源还是西方,都是用英语的,那我们就拿最早的ASCII编码来举例,就比如一个大写字母“A”,这个“A”在ASCII码表里面的编号(十进制码点)是65,十六进制码点是41(4*16+1=65),在计算机里储存用的是二进制码点,也就是01000001这个8位(8bit=1byte,也就是8位就是一个字节)的二进制储存。如下图

因为ASCII是固定只有1字节的,如此一来,ASCII码表只能储存0-127,这128个码点对于 储存英文字母,数字,英文符号已经是足够了。

但是但是但是,你英文字母少可以靠ASCII的规则储存,那我中国汉字那么多,无法使用ASCII码表储存,那我就不能用电脑了?

所以,各国开始制定自己的编码规定,比如中国就制定了GB2312,GB2312是两个字节的编码,可以储存常见汉字6800多个,还有中文符号,但是这些汉字都是简体汉字,所以但是中国台湾地区还流行大五码(big-5),big-5也是2个字节的编码,可以储存繁体汉字,包含了13000以上的汉字。

但是之后中国大陆和中国台湾更换,使用了新的GBK编码,GBK完全兼容GB2312,GBK同样使用双字节的编码。

说完中国,我们回望国际,国际上一直想采用一种可以兼容所有语言的编码,于是unicode的UTF-32(也就是万国码)横空出世,UTF-32因为其4字节的长度,可储存大量的编码,但是也正是如此,采用UTF-32的文件会占用更大的空间。。就比如一个纯英文文本,采用ASCII编码只有采用UTF-32的1/4。如此一来,空间利用率会大大降低。

最后讲一下我们现如今最普及的UTF-8编码,UTF-8采用可变长度的编码,这种编码可以细嗦一下,UTF-8占用1到6个字节长度,而且UTF-8的码表前127位和ASCII完全相同,这也就是说,UTF-8完全兼容ASCII编码。

下面细嗦UTF-8的编码规则,其实也就类似于高中生物学习的启动子。

因为UTF-8是可变长度的编码,所以问题就是在于,如何识别截断每个字符的编码,比如给一组11110111 10001101 10100101 10101101 这么一段编码,该如何去读取截断呢?它是4个1byte的字符还是,2个2byte的字符,还是1个1byte和1个3byte字符的组合。

UTF-8的规则就是(字母都代表的是0或者1)

1byte的编码采用0xxxxxxx的方式储存,0就是读取的关键,意味着这段二进制数字是表示一个字符,而这7个x才是真正储存的信息的地方。

2byte的编码采用110xxxxx 10yyyyyy(对应的二进制数字是xxxxxyyyyyy)的方式储存,“110”里面有两个1 ,意味着这第一段和第二段两串二进制数字才决定一个字符,这样读取的时候就会同时读取2byte的内容了, x和y连起来,对应的就是这串数字的二进制码点了。

3byte编码是采用1110xxxx 10yyyyyy 10zzzzzz,“1110”里的三个1,代表从读取到1110往后连着一同读取3个字节。xxxxyyyyyyzzzzzz代表的就是这个数字的二进制码点。

以此类推......

6byte的编码采用1111110x 10yyyyyy 10zzzzzz 10 10wwwwww 10vvvvvv来表示。

如今,UTF-8已经成为了主流的编码。普及率已经达到了50%以上。但是仍然要注意有时候UTF-8是否在当前形式是默认编码或者是否兼容,Python2默认采用的是ASCII编码,Python3默认采用的是UTF8编码。在Python2和Python3里面读取汉字的长度会不一样

比如:在Python2中输入len("你就是歌姬吧") ,运行的结果就是18,这是因为在Python2中,没有把汉字当成一个整体,只是在读字节的数量(每个汉字占3个字节),所以就会输出18

但是在Python3中输入len("你就是歌姬吧"),结果确实正常的6,就是因为Python3默认采取UTF-8编码,所以可以正确读取字符串的长度.

--------------------------------------------------------------------------------------------------

终于也算是写了一点算是干货的东西

相关文章