[计算机原理] 字符编码的发展历史

什么是字符编码

计算机的最小存储单元是二进制位,叫做bit,可以表示01两种状态,8个连续的二进制位组合出一个字节,叫做byte,可以表示出256种状态,二进制是0000000011111111,十进制是0 ~ 255

明确两个概念:

  1. 字节是计算机存储数据的基本单位!
  2. 字符是人类文明创造的符号,汉字、英文字母、标点符号、特殊符号都是字符。

字符编码就是在字节和字符之间建立一个映射关系!使得计算机可以用字节存储字符!

ASCII

计算机起源于二十世纪的美国,美国率先制定出一套字符编码方案,将33个不可见的控制符号和95个可见的符号(数字、英文大小写字母、特殊符号)共计128个,与单个字节中0000000001111111128种状态做了一一对应。这就是著名的ASCII编码,它是个单字节的编码方案。

因为英语的符号很少,所以美国人使用计算机时用ASCII编码存储英文信息足够,但是世界上除了英语,还有汉语和其它地区的语言,这些文明所包含的符号就远超128个,ASCII编码最多只能存储256个字符,根本就不够用,这时候就该发明新的编码方式了。

扩展字符集

刚刚说了一个字节可以表示256种状态,ASCII编码占用了其中128种,还剩128种未被占用,它们是1000000011111111,把这些空位置再利用上表示新的字符,就诞生了“扩展字符集”编码。“扩展字符集”现在已经没有太多实用价值了,基本被淘汰的差不多了。

至此,基於单字节的编码方案再无新的扩展。

计算机来到中国以后

计算机晚些时候才传入中国,中国人要用计算机存储汉语字符。但是,汉语符号太多了,常用汉字就有6000多个,全部汉字加起来要以万为单位来计算,采用单字节编码方案肯定行不通,那就用两个字节吧,两个字节有16bit能组合出65536种状态,嗯,差不多了,能表示很多汉字了。

一个字节可以编码一个英文字母,两个字节可以编码一个汉字。这个时候问题就来了:两个字节放在你面前,到底是表示一个汉字?还是两个英文字母?

中国人意识到这是一个规则漏洞!那就再加些规则限制一下:单字节ASCII编码方案利用了一个字节的前128种状态,后128种状态未被利用,那就规定表示汉字的两个字节必须使用后128种状态,前面的称为高字节,后面的称为低字节,高低字节组合起来能表示大约16384种状态,也就是一万多个字符,日常够用。

问题解决了么?解决了,两个字节摆在面前,如果字节状态在前128种之内,就是两个英文字母,如果字节状态在后128种之内,就是一个汉字。

两字节的16384种状态并没有全部拿来编码汉字,汉字只占用了7000多个常用的,其余的状态还编码了部分数学符号、罗马希腊字母、日文假名等。不仅如此,ASCII中的数字、标点、字母也被分配有新的状态,为了加以区分,原ASCII中单字节字符的叫做“半角”字符,新的双字节字符叫做“全角”字符。中国人管这种编码方案叫GB2312,是对ASCII的中文扩展。

慢慢的GB2312的问题也显露出来,这套编码只有大约7000个汉字,其它生僻汉字的编码问题也要解决。那就把GB2312的规则再扩展一下:不再要求低字节必须使用后128种状态,只要高字节是后128种状态就行,这样就又能扩展出大约20000个新状态,又能表示好多汉字了。这套编码叫做GBK

少数民族使用计算机后,GBK又扩展出了GB18030编码,收录了很多少数民族的语言符号。

中国人发明出来的编码统称为“双字节字符集”,英语全称Double Byte Charecter Set,简称DBCS,它最大的特点就是单字节编码和双字节编码可以共存!这无意间给中国码农们造就了一个巨大的bug隐患!敲代码时要时刻牢记“一个英文占一个字节的存储空间,一个汉字占两个字节的存储空间”。

Unicode 全球化进程

到目前为止,编码还是区域化的,因为各地区字符集不同,所以各国家各地区都在使用自己的编码方案,彼此之间不理解也不支持。中国大陆使用GBK编码,台湾使用BIG5编码,如果大陆计算机要浏览台湾的繁体字网页,就要先给计算机装上BIG5编码,然后才能正确解析台湾的网页,否则解析出来的就是一堆乱码。我就想访问个网页,还要先装个编码,这真是个烦人的事情!

……

很久以后,出现了一个全球性的非政府组织,叫做国际标准化组织,全称是International Organization for Standardization,简称ISO。他们想解决区域性编码这个烦人的事情,提出一个解决方案:废除所有地区性的编码,重新搞一个全球化的编码,包含全世界所有的符号!他们给这套编码方案起了一个响亮的名字Universal Multiple-Octet Coded Character Set,简称UCS,俗称UNICODE。其编码理论就是把全世界所有字符统一收集起来,给每个符号分配一个编号,从0开始往后递增,全世界公认这个字符编号。编号就是一个唯一的值,正式名字叫做“码点”Code Point,其表现形式可以是二进制,也可以是十进制。

全球公认的字符编号就是UNICODE最大的价值所在!它是一套完整的字符集标准,定义了字符与编号之间的映射关系,全世界任何一个字符都能在这里找到。字符具体的存储方式规定的也很简单:单个字符统一用两个字节或者四个字节存储。

两个字节存储一个字符的方案叫做UCS-2,是UNICODE的一个子集,只能表示出0 ~ 65535这么多的字符,绝大多数时候够用。

四个字节存储一个字符的方案叫做UCS-4,是UNICODE更大范围的一个子集,能表示出更多的字符,目前足够容纳全世界所有的字符。

无论是UCS-2还是UCS-4都存在一个问题,就是字节空间的浪费,原本一个字节就能存储的字符现在必须要用两个或是四个字节。据统计,计算机中使用最多的字符还是英文,ASCII只需要一个字节就能存储,改用UNICODE就是成倍的浪费。

对于绝大多数人来说,这辈子UCS-2字符集就完全够用了,所以UNICODE字符集范围虽然很大很大,但是日常交流中说到UNICODE更多的就是指代UCS-2字符集。

UTF-X 家族

互联网兴起后,事情开始有了新的进展。UNICODE网络传输是必须要思考的,传输中大量浪费字节位可不行,于是众多面向传输的UTF(UCS Transfer Format)标准出现了,常见的有:UTF-8UTF-16UTF-32。它们遵循UNICODE字符集标准,但却改变了它的字节存储方案。

下面对于UTF的分析就局限在UCS-2字符集范围内,UCS-4是同理的。具体存储细节不展开细说了。

UTF-8最小存储单位是8bit,也就是一个字节,用它存储字符,英文只需要一个字节,汉字通常需要三个字节。所以这种编码方案很适合英文字符集多的场景使用。

UTF-16类似,区别在于最小存储单位是16bit,也就是两个字节,存储英文和汉字都需要两个字节,所以该方案适合汉字量居多的场景。它和UCS-2的存储方案很类似,可以说就是一样的东西。

UTF-32还是类似的,只不过最小存储单位是四个字节,这是为UCS-4字符集准备的。

UNICODE本是“字符集定义”和“存储方案”集于一身的,但是因为其自身的存储传输效率不高,很长一段时间内,推广都不是那么的顺利。后来出现的UTF家族提高了存储传输效率,两者相辅相成,UNICODE得以顺利推广,成为编码界的泰山北斗。在现有的体系下,UNICODE代表的是字符集标准,UTF-X代表的是具体的编码实现。

写在后面

这是很久以前写的一篇文章,大概五年前吧,一直没发出来。

当时看到了一篇别人写的很好的博客,在那个基础上加以理解吸收后,形成了自己的这篇博文,是原创,但也算不上是绝对的原创吧。

很可惜,之前看到的那篇博客,我现在已经找不到了,无论如何,感谢那个无名的“前浪”!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章