在谈论这个问题之前,我们首先想想一下我们在写代码时候常常遇到的一些“神仙问题”,各种乱码事件想必大家肯定是深恶痛绝。一看到“锟斤拷”就想打人。那么实际上乱码的出现就是因为字符串的编码方式不同而导致的情况。
说到这里,我们大家肯定有迷惑又好奇,为什么我们这个世界上存在这么多的编码,像什么ASCII
,GBK
,UTF-8
之类的编码什么的。而且一旦中文乱码,我们都是采用将编码格式调整到UTF-8
来解决。那么大家有没有想过为什么会出现这么多这样那样的编码呢?
整理自这篇blog。
这篇也讲得不错。
一、创造者的编码
众所周知,计算机是老美率先发明创造的智慧的结晶,那么在最初的时候,老美根本没想到计算机会如此普及。鉴于英语的组成又是十分的简单——只需要
26
26
26个英文字符和一些标点符号还有数字。于是他们使用了
127
127
127个字符将以上的这些编码导入计算机中,以便计算机能够处理他们的文字。这就是我们所熟知的ASCII
码。在ASCII
码中,采用的是一个字节的后七位来表示的。最高位统一编码为零。
二、欧洲的编码
随着世界各国的交流和合作越来越紧密,计算机传到欧洲各国家之后,就出现了问题。就拿法文来说,我们的法文除了你拉丁字母之外,还有注音符!就是这么优秀,遇到这种情况。这怎么搞,这不是破坏大一统的格局吗?法国人一想,我们也要把自己的文字编入到计算机!于是他们将ASCII
中的没有使用的最高位也拿过来使用了。这样最多能够表示
2
8
=
256
2^8=256
28=256位,这下好了这一下就解决了当务之急。
三、睡狮的编码
以上的这些“小聪明”也只是暂时解决了当务之急,当计算机传入到中国之后。这些可真是“摊上大事了”,我们中国的汉字,少说也有
10
10
10多万。这下以上的一个字符编码已经完全不够塞牙缝的。然后我们勤劳的中国人也创造了一种属于自己的编码——gb2312
,就是我们常说的两个字节表示一个中文汉字的方法。这样也仅仅把一些常用的汉字表示出来(只能显示
2
16
=
65526
2^{16}=65526
216=65526个字符)。这就是当我们采用gb2312
编码的时候,一些复杂的字符我们不能显示出来的原因。到这里,勉强解决了每个国家自己的字符编码规则。
四、难得的大一统
别以为到这里就结束了!其实以上的这些操作导致了一个更大的问题!如果我们同一个语言区相互交流,这是什么问题都没有。但是试想,我们中国人收到一封来自俄国的邮件。一打开全是乱码。这下就尴尬了,虽然各个国家都有一套自己的编码,但是同一个编码在每个国家的含义不同。这样情况下怎么办呢?全球统一编码呗——于是Unicode
就出现了。这就解决了我们的编码问题!这才短暂告一段落。
五、追求传输速度
问题似乎被很简单的解决了。可是大家试想,如果我们的一篇文章当中,大部分全是英文。由于还是需要使用Unicode
进行编码,那么大量的编码全部是无意义的填充字符
0
0
0,这就大大的耗费了存储空间。而且一旦这些数据需要在网上传输,就会消耗更多的网络资源。这个时候,人们又想出一种全新的编码方式——变长的编码模式,其中最常用的就是我们所说的UTF-8
。那么有人会问了,变长字符是怎么知道结束字符的呢?其实很简单,如果一个字符中的最高位——也就是在ASCII
码中被空出来的一位中为
0
0
0,则表示该字符是最后一个了。但是如果最高位是
1
1
1,那么表明该字符后面还有。从这个角度上看,传输纯英文的文件就会节省很多空间。
最重要的是,从以上的分析我们可以得知,ASCII
码是包含在UTF-8
编码规则中的。也就是说以前那些只支持ASCII
编码的软件依然可以在UTF-8
的环境中完美运行。另外在UTF-8
中,中文所占的字符是
3
3
3个。
编码方式 | 中文字母 | 英文字母 |
---|---|---|
GB2312 | 2 | 1 |
GBK | 2 | 1 |
GB18030 | 2 | 1 |
ISO-8859-1 | 1 | 1 |
UTF-8 | 3 | 1 |
UTF-16 | 4 | 4 |
UTF-16BE | 2 | 2 |
UTF-16LE | 2 | 2 |