首页 > 技术文章 > 字符编码的发展

wzcc 2021-11-17 19:29 原文

1、字符码的出现

 

我们都知道,计算机只能处理数字,即0和1,如果要处理文本,就必须先把文本转换为数字才能处理。最早的计算机在设计时采用8个比特(bit)作为一个字节(byte),所以,一个字节能表示的最大的整数就是255(二进制11111111=十进制255),如果要表示更大的整数,就必须用更多的字节。比如两个字节可以表示的最大整数是65535,4个字节可以表示的最大整数是4294967295。

2、ASCII的由来

由于计算机是美国人发明的,所以只出现大小写英文字母、数字和一些符号。因此,最早只有127个字符被编码到计算机里,也就是7位2进制数字,最高位(第八位)为0。这个编码表被称为ASCII编码,比如大写字母A的编码是65,小写字母z的编码是122。

3、Unicode的由来

 UCS-4编码推出之后遭受到了美国的大公司的反对,当时由施乐公司牵头,联合了Google、Micro Soft、IBM、Oracle、SUN、Apple等公司成立了Unicode委员会,研发自己的编码和解码规范,然后推出了Unicode1.0编码规范。Unicode1.0采用双字节编码,收录了世界上大部分常用的字符。在这段时间就出现了两个不同的规范。ios和Unicode组织也意识到了这个问题的严重性,于是两者开始对话。最终的结果是:将Unicode的双字节编码,纳入到UCS编码规范的0组0面。
      UCS-4的0组0面也称为基本多语言平面(Basic MultiLanguage Plain)也就是说UCS-4的高2字节都为的时候称为BMP,BMP和UCS-4的转换也很简单,在BMP的高位添加两个字节的0就称为UCS-4,将UCS-4的高二字节都变成0就变成了BMP。

4、UTF-8的由来
现在,捋一捋ASCII编码和Unicode编码的区别:ASCII编码是1个字节,而Unicode编码通常是2个字节。

字母A用ASCII编码是十进制的65,二进制的01000001;

字符0用ASCII编码是十进制的48,二进制的00110000,注意字符’0’和整数0是不同的;

汉字中已经超出了ASCII编码的范围,用Unicode编码是十进制的20013,二进制的01001110 00101101。

你可以猜测,如果把ASCII编码的A用Unicode编码,只需要在前面补0就可以,因此,A的Unicode编码是00000000 01000001。

新的问题又出现了:如果统一成Unicode编码,乱码问题从此消失了。但是,如果你写的文本基本上全部是英文的话,用Unicode编码比ASCII编码需要多一倍的存储空间,在存储和传输上就十分不划算。

所以,本着节约的精神,又出现了把Unicode编码转化为“可变长编码”的UTF-8编码。UTF-8编码把一个Unicode字符根据不同的数字大小编码成1-6个字节,常用的英文字母被编码成1个字节,汉字通常是3个字节,只有很生僻的字符才会被编码成4-6个字节。如果你要传输的文本包含大量英文字符,用UTF-8编码就能节省空间。

我们还可以发现,UTF-8编码有一个额外的好处,就是ASCII编码实际上可以被看成是UTF-8编码的一部分,所以,大量只支持ASCII编码的历史遗留软件可以在UTF-8编码下继续工作。

 

下表总结了编码规则,字母x表示可用编码的位。

Unicode符号范围 | UTF-8编码方式
(十六进制) | (二进制)
——————–+———————————————
0000 0000-0000 007F | 0xxxxxxx
0000 0080-0000 07FF | 110xxxxx 10xxxxxx
0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

下面,以汉字“严”为例,演示如何实现UTF-8编码。
已知“严”的unicode是4E25(100111000100101),根据上表,可以发现4E25处在第三行的范围内(0000 0800-0000 FFFF),因此“严”的UTF-8编码需要三个字节,即格式是“1110xxxx 10xxxxxx 10xxxxxx”。然后,从“严”的最后一个二进制位开始,依次从后向前填入格式中的x,多出的位补0。这样就得到了,“严”的UTF-8编码是“11100100 10111000 10100101”,转换成十六进制就是E4B8A5。

5、GBK

 当计算机传出到中国之后,国家也面临字符编码相关的工作,所以当时就推动制定了一套双字节编码编码规范,他收录了常见的6000多个中文、东亚文字以及欧美文字,所有的字母采用两个字节进行编码,称为GBK,由于微软等公司的支持,所以GBK在中国很流行,以至于现在的很多小企业还是采用GBK编码。

6、实现方式
Unicode的实现方式不同于编码方式。一个字符的Unicode编码是确定的。但是在实际传输过程中,由于不同系统平台的设计不一定一致,以及出于节省空间的目的,对Unicode编码的实现方式有所不同。
Unicode的实现方式也称为Unicode转换格式(Unicode Transformation Format,简称为UTF),目前主流的实现方式有UTF-16和UTF-8。随着Unicode通用字符集的扩充,进而出现了UTF-32,但是由于占用空间太大,目前很少有系统选择使用utf-32作为系统编码。

7、字符乱码

当计算机只是在本地(使用一种字符编码的范围内的地区)使用和传播的时候不会出现什么问题,但是当不用的区域需要进行信息交换的时候就会出现问题,比如中国和欧洲进行字符交换,中国使用GBK编码,欧洲使用EASCII编码。那么会出现这样一种情况,一个中国的汉字,被显示为连个奇怪的西欧字符,看到上面的历史,应该明白原因了吧。

8、UCS系列

      随着信息交流越来越频繁。字符乱码的问题也就越来越突出,统一编码的需求也就越来越强烈。所以IOS组织就提出了一个统一的编码方案。大致的规则如下:

    • 所有的字符采用四个字节进行编码。
    • 将整个编码空间划分为(组,面,行,列)四个部分,并且最高位固定为0,所以一共可以表达的字符个数为 128*255*255*255 总共可以表示2亿多个字符。
            因为当时采用了四字节的编码方式,所以这种编码方式又称为 UCS-4。

 

推荐阅读