文章原写于2019年,时值初一年级,定有错漏之处。敬请见谅。

绪言

  不知各位小伙伴们在日常生活当中有没有碰到过文件乱码的情况。同一串字符,在不同的地方,显示出的内容确有差异。但现今,这种情况已经非常罕见了。那么,为什么会出现乱码?乱码的现象为什么变得罕见了呢?这就是本期严石要与大家讨论的话题:编码。

编码

ASCII编码

  地球人都知道,机器不如人类(比如严石这类生物体 \手动滑稽)这样机智聪明,它们只能识别二进制,即0或1。但是,仅仅用数字0或1,如何能表示文字呢?很简单,我们可以制成一张表,以此来规定用怎样的“0”与“1”的组合表示出怎样的文字。由于计算机最早是美国发明的,故在文字的ASCII编码中只顾及到了英文字母。我们可以用一个字节(注:1 type = 8 bit)的长度表示出255种“0”与“1”的组合。因为,“0”或“1”这种数字占1个bit的长度,而一个字节有8个bit,故总共有$2^8-1=255$种变换。

例如:0000 0001;0000 0010;0000 0011等等共256种变换。

  255种变换足以表示26个字母,10个阿拉伯数字以及各种标点符号。所以,很久以来,计算机都采用了ASCII编码。ASCII是(American Standard Code for Information Interchange)的缩写,意思是:美国信息交换标准码。确实,文字方面,此编码只能表示英文字母,配得上美国二字。

  查表可看出,大写字母“A”的ASCII值是65,将65转换成二进制为0100 0001,因此当以ASCII编码时读到0100 0001,计算机即转换为大写字母A。

  随着科技的发展,计算机在各国都得到了普及,可ASCII编码只能表示英文,无法展现出中文、日文、韩文等其它文字,怎么办呢?

ANSI编码

  这很简单,世界各国又根据自己的文字制定出了符合自己文字的编码。这些各国自己的编码实际上是对于ASCII的扩展。ANSI编码事实上是简体中文、繁体中文、日文、韩文等各种不同编码的总称。

GBK编码

  GBK即“国标”、“扩展”汉语拼音的第一个字母,全称《汉字内码扩展规范》。由于1个字节仅能表示255种不同变换,而汉字远不止255个,于是该编码采用的双字节,2个字节即16比特,能表现出2^{16}-1=65535种变换,表现汉字就绰绰有余了。而GBK属于变长字符集,对于英文仍旧采用1个字节表示,兼容ASCII编码。而对于中文则采用2个字节。

  GBK编码是中国早期制定的汉字编码GB 2312编码的扩充,完全包含了GB 2312的所有编码,又对GB 2312的编码有所扩充。这里就不展开来叙述了。

GB 18030编码

  GB 18030编码同GBK编码一样,都是中国制定的编码,它也是一个变长字符集。它对GB 2312完全向后扩展兼容,对GBK基本向后扩展兼容。它共收录了汉字70244个,采用1个、2个或4个字节交换信息。因此,它完全支持Unicode,无需动用造字区即可支持中国国内少数民族文字、中日韩和繁体汉字以及emoji等字符。此编码很强大。

Big 5编码

  ASCII编码不能表示繁体中文,所以中华人民共和国的港澳台地区又自己鼓捣了一个编码,叫做Big 5码,很好地表现了繁体中文。

乱码

  但这就出现了问题,一份在台湾省采用Big 5编码的文字“我愛你”,实际存储在计算机里的信息是:“A7DA B752 A741”(十六进制下)。然后,这份文件传输到中国大陆,而大陆的标准是GBK、GB 2312或GB 18030编码。假设大陆这边使用GBK编码打开这份Big 5编码的文件,计算机就会在GBK编码库中寻找“A7DA B752 A741”(十六进制下)。OK,计算机找到了。“A7DA”在Big 5编码中是“我”字,而在GBK编码中是“и”这个字。同理,“B752”在GBK编码中对应的字是“稲”,而“A741”在GBK编码中没有字符。

  于是乎,来自台湾省的“我愛你”,到了大陆这边,却显示出了“и稲 ”这种没有意义的字符。所以,乱码出现了。

  小伙伴们又问了,GB 18030不是支持繁体字符吗?可以用GB 18030来读Big 5啊!可惜,遗憾的是GB 18030与Big 5不兼容,并不是同一个繁体字在两种编码体系中都用一种编码表示。因为是在对GB 18030对GB 2312和GBK兼容的情况下扩展的,所以在这三种编码(GBK、GB 2312、GB 18030)中,同一个字的编码表示基本是相同的。在GB 18030下,“我愛你”变成了“и稲”。

  所以,下一次你打开一份来自港澳台地区的文件,却显示“и稲”的话,他实际上是在和你表白!

  同一份文件在不同编码表示的含义根本就不一样。这怎么能行?于是,一个神秘的编码横空出世。

UNICODE

  此编码骨骼清奇,于1990年研发,又称作万国码。因为它收录了世界几乎所有的文字。所谓Unicode,就是United code,联合起来的码。每一种文字在上面都有自己独一无二的编码。

  既然Unicode啥都能表示,那还需要自己的那么局限的编码干什么?全世界都用Unicode岂不美哉,这样就避免了乱码。所以,Windows默认的记事本采用的就是带BOM的UTF-8格式,即采用了Unicode。因此,在大家的共同努力下,乱码的情况越来越少。

最后修改:2025 年 03 月 14 日
如果觉得我的文章对你有用,请随意赞赏