编码

在计算机种中,1字节对应8位二进制数,而每位二进制数有0、1两种状态,因此1字节可以组合出256种状态。如果这256中状态每一个都对应一个符号,就能通过1字节的数据表示256个字符。美国人于是就制定了一套编码,描述英语中的字符和这8位二进制数的对应关系,这被称为ASCII码。

ASCII 码一共定义了128个字符,例如大写的字母A是65(这是十进制数,对应二进制是0100 0001)。这128个字符只使用了8位二进制数中的后面7位,最前面的一位统一规定为0。

英语用128个字符来编码完全是足够的,但是用来表示其他语言,128个字符是远远不够的。于是,一些欧洲的国家就决定,将ASCII码中闲置的最高位利用起来,这样一来就能表示256个字符。但是,这里又有了一个问题,那就是不同的国家的字符集可能不同,就算它们都能用256个字符表示全,但是同一个码点(也就是8位二进制数)表示的字符可能可能不同。例如,144 在阿拉伯人的ASCII码中是 گ,而在俄罗斯的ASCII 码中是 ђ

因此,ASCII 码的问题在于尽管所有人都在 0 – 127 号字符上达成了一致,但对于 128 – 255 号字符上却有很多种不同的解释。与此同时,亚洲语言有更多的字符需要被存储,一个字节已经不够用了。于是,人们开始使用两个字节来存储字符。

各种各样的编码方式成了系统开发者的噩梦,因为他们想把软件卖到国外。于是,他们提出了一个内码表的概念,可以切换到相应语言的一个内码表,这样才能显示相应语言的字母。在这种情况下,如果使用多语种,那么就需要频繁的在内码表内进行切换。

最终,美国人意识到他们应该提出一种标准方案来展示世界上所有语言中的所有字符,出于这个目的,Unicode诞生了。

Unicode当然是一本很厚的字典,记录着世界上所有字符对应的一个数字。具体是怎样的对应关系,又或者说是如何进行划分的,就不是我们考虑的问题了,我们只用知道Unicode给所有的字符指定了一个数字用来表示该字符。

对于Unicode有一些误解,它仅仅只是一个字符集,规定了符合对应的二进制代码,至于这个二进制代码如何存储则没有任何规定。它的想法很简单,就是为每个字符规定一个用来表示该字符的数字,仅此而已。

之前提到,Unicode 没有规定字符对应的二进制码如何存储。以汉字为例,它的Unicode码点是0x6c49,对应的二进制数是110110001001001,二进制数有15位,这也就说明了它至少需要2个字节来表示。可以想象,在Unicode字典中往后的字符可能就需要3个字节或者4个字节,甚至更多字节来表示了。

这就导致了一些问题,计算机怎么知道你这个2个字节表示的是一个字符,而不是分别表示两个字符呢?这里我们可能会想到,那就取个最大的,假如Unicode中最大的字符用4字节就可以表示了,那么我们就将所有的字符都用4个字节来表示,不够的就往前面补0。这样确实可以解决编码问题,但是却造成了空间的极大浪费,如果是一个英文文档,那文件大小就大出了3倍,这显然是无法接受的。

于是,为了较好的解决Unicode 的编码问题,UTF-8UTF-16两种当前比较流行的编码方式诞生了。当然还有一个UTF-32的编码方式,也就是上述那种定长编码,字符统一使用4个字节,虽然看似方便,但是却不如另外两种编码方式使用广泛。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注