字符编码的前世今生

Posted yxysuanfa

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了字符编码的前世今生相关的知识,希望对你有一定的参考价值。

文章来源:字符编码的前世今生


因为“字符编码”这个话题牵涉到的历史久远、机构众多、专业术语较多。所以本篇文章可能会略长,为了避免内容过于枯燥。我会尽量用一种通俗易懂的语言来写这篇文章。


当中本文的第一篇章会对历史中的主要字符编码进行介绍。因为篇幅较长,假设读者对此已非常了解。可直接跳过进行第二章的阅读。


完毕本篇文章的过程中參考和阅读了大量的文章和文献,写本篇文章的目的一是让自己对“字符编码”可以做一个较深的理解。二是希望给以前徘徊或正在徘徊在编码困惑中的前端们一个非常好的參考,搞清楚字符编码问题是前端万事之基石。


因为本人才疏学浅,好多信息也是从网络和书籍中參考而来。错误之处难免。请大家指正。


------------------题记

 

尾随历史的足迹看字符编码

 

古代的通信方式

 

非常久非常久曾经,人们之间的长途通讯主要是用信鸽、骑马送报、烽烟等方式进行:

 

世界第一条电报

 

直到1837年,世界第一条电报诞生。当时美国科学家莫尔斯尝试用一些“点”和“划”来表示不同的字母、数字和标点符号。这套表示字符的方式也被称为“摩尔斯电码”:

 

 

世界第一台计算机

 

再后来到了1946年,世界第一台计算机诞生。发明计算机的同学们用8个晶体管的“通”或“断”组合出一些状态来表示世间万物。只是当时的计算机有一间半教室那么大,六头大象重。从如今看来这简直就是个怪物。但在当时却是震惊世界与改变世界的一项重要发明:

 

ASCII

 

8个晶体管的“通”或“断”即能够代表一个字节。刚開始,计算机仅仅在美国使用。全部的信息在计算机最底层都是以二进制(“0”或“1”两种不同的状态)的方式存储,而8位的字节一共能够组合出256(2的8次方)种状态,即256个字符,这对于当时的美国已经是足够的了,他们尝试把一些终端的动作、字母、数字和符号用8位(bit)来组合:

 

  • 0000 0000 ~ 0001 1111 共 33 种状态用来表示终端的特殊动作,如打印机中的响铃为 0000 0111 ,当打印机遇到 0000 0111 这种字节传过来时,打印机就開始响铃。

 

  • 0010 0000 ~ 0010 1111 、 0011 1010~0110 0000 和 0111 1101 ~ 0111 1110 共 33 种状态来表示英式标点符号。如 0011 1111 即代表英式问号“?

    ”;

 

  • 0011 0000 ~ 0011 1001 共 10 种状态来表示“0~9”10个阿拉伯数字;

 

  • 0100 0001 ~ 0101 1010 和 0110 0001 ~ 0111 1010共 52种状态来表示大写和小写英文字母;

自此,一共仅仅用到了128种状态。即128个字符,刚好占用了一个字节中的后7位,共包含33个控制字符和95个可显示字符,这一字符集被称为ASCII(American Standard Code for Information Interchange,美国信息交换标准代码,这一套字符集在1967年被正式发布。

 

说到这里,引出几个基础概念:

 

  • 比特(bit):也可称为“位”。是计算机信息中的最小单位,是 binary digit(二进制数位) 的 缩写,指二进制中的一位

 

  • 字节(Byte):计算机中信息计量的一种单位。一个位就代表“0”或“1”,每8个位(bit)组成一个字节(Byte)

 

  • 字符(Character):文字与符号的总称,能够是各个国家的文字、标点符号、图形符号、数字等

 

  • 字符集(Character Set):是多个字符的集合

 

  • 编码(Encoding): 信息从一种形式或格式转换为还有一种形式的过程

 

  • 解码(decoding): 编码的逆过程

 

  • 字符编码(Character Encoding): 依照何种规则存储字符

如今我们来看我们文章开头提到的第一条电报的诞生,莫尔斯编码中包括了大写和小写英文字母和数字等符号。

  • 这里的每个符号事实上就是⌈字符⌋
  • 而这全部的字符的集合就叫做⌈字符集⌋
  • “点”或“划”与字符之间的相应关系即能够称为⌈字符编码⌋

而电报的原理是:

“点”相应于短的电脉冲信号,“划”相应于长的电脉冲信号。这些信号传到对方。接收机把短的电脉冲信号翻译成“点”。把长的电脉冲信号转换成“划”。译码员依据这些点划组合就能够译成英文字母,从而完毕了通信任务。
  • 这里把字符表示为“点”或“划”并相应为电脉冲信号的过程既是⌈编码⌋

 

  • 而译码员把接收机接收到的脉冲信号转化成点划后译成字符的过程即为⌈解码⌋

而对于计算机诞生之后,仅仅只是是将摩斯电码中的“点”和“划”换成了以8位字节二进制流的方式表示。如数字1的二进制流是0011 0001。相应的十进制流是49。十六进制流是31。

 

EASCII

 

尽管刚開始计算机仅仅在美国使用,128个字符的确是足够了,但随着科技惊人的发展。欧洲国家也開始使用上计算机了。

只是128个字符明显不够呀,比方法语中,字母上方有注音符号,于是。一些欧洲国家就决定。利用字节中闲置的最高位编入新的符号。比方,法语的é的二进制流为1000 0010,这样一来。这些欧洲国家的编码体系,能够表示最多256个字符了。

可是,这里又出现了新的问题。不同的国家有不同的字母。因此,哪怕它们都使用256个符号的编码方式,代表的字母却不一样。比方,1000 0010在法语编码中代表了é,在希伯来语编码中却代表了字母Gimel (?

)。在俄语编码中又会代表还有一个符号。可是无论如何。全部这些编码方式中,0--127表示的符号是一样的,不一样的仅仅是128--255的这一段。 EASCIIExtended ASCII,延伸美国标准信息交换码)由此应运而生,EASCII码比ASCII码扩充出来的符号包含表格符号、计算符号、希腊字母和特殊的拉丁符号:

 

 

GB2312

 

EASCII码对于部分欧洲国家基本够用了。但过后的不久,计算机便来到了中国,要知道汉字是世界上包括符号最多而且也是最难学的文字。 据不全然统计。汉字共包括了古文、现代文字等近10万个文字,就是我们如今日经常使用的汉字也有几千个。那么对于仅仅包括256个字符的EASCII码也难以满足天朝的需求了。 于是⌈中国国家标准总局⌋(现已更名为⌈国家标准化管理委员会⌋)在1981年,正式制订了中华人民共和国国家标准中文简体字符集,全称信息交换用汉字编码字符集·基本集》,项目代号为GB 2312 或 GB 2312-80(GB为国标汉语拼音的首字母)。此套字符集于当年的5月1日起正式实施。

 

包括字符:

 

共包括7445个字符,6763个汉字和682个其它字符(拉丁字母、希腊字母、日文平假名及片假名字母、俄语西里尔字母)

 

存储方式:

 

基于EUC存储方式,每一个汉字及符号以两个字节来表示。第一个字节为“高位字节”,第二个字节为“低位字节”

 

BIG5

 

要知道港澳台同胞使用的是繁体字。而中国大陆制定的GB2312编码并不包括繁体字,于是信息工业策进会在1984年与台湾13家厂商签定“16位个人电脑套装软件合作开发(BIG-5)计划”。并開始编写并推出BIG5标准。 之后推出的倚天中文系统则基于BIG5码。并在台湾地区取得了巨大的成功。在BIG5诞生后,大部分的电脑软件都使用了Big5码。BIG5对于以台湾为核心的亚洲繁体汉字圈产生了久远的影响。以至于后来的window 繁体中文版系统在台湾地区也基于BIG5码进行开发。

 

包括字符:

 

共收录13,060个汉字及441个符号

 

编码方式:

 

用两个字节来为每一个字符编码,第一个字节称为“高位字节”,第二个字节称为“低位字节”

 

Unicode

 

由来:

 

在计算机进入中国大陆的同样时期,计算机也迅速发展进入了世界各个国家。

特别是对于亚洲国家而言。每一个国家都有自己的文字。于是每一个国家或地区都像中国大陆这样去制定了自己的编码标准,以便能在计算机上正确显示自己国家的符号。

但带来的结果就是国家之间谁也不懂别人的编码,谁也不支持别人的编码,连大陆和台湾这样仅仅相隔了150海里,都使用了不同的编码体系。 于是,世界相关组织意识到了这个问题,并開始尝试制定统一的编码标准。以便可以收纳世界全部国家的文字符号。 在前期有两个尝试这一工作的组织:

 

  • 国际标准化组织(ISO)

 

  • 统一码联盟

 

国际标准化组织(ISO)及国际电工委员会(IEC)于1984年联合成立了ISO/IEC小组,主要用于开发统一编码项目。 而Xerox、Apple等软件制造商则于1988年组成了统一码联盟,用于开发统一码项目。

两个组织都在编写统一字符集,但后来他们发现各自在做同样的工作。同一时候世界上也不须要两个不兼容的字符集,于是两个组织就此合并了两方的工作成果,并为创立一个单一编码表而协同工作。

 

1991年。两个组织共同的工作成果Unicode 1.0正式公布,只是Unicode 1.0并不包括CJK字符(即中日韩)。

 

  • Unicode 1.0:1991年10月
  • Unicode 1.0.1:1992年6月
  • Unicode 1.1:1993年6月
  • Unicode 2.0:1997年7月
  • Unicode 2.1:1998年5月
  • Unicode 2.1.2:1998年5月
  • Unicode 3.0:1999年9月
  • Unicode 3.1:2001年3月
  • Unicode 3.2:2002年3月
  • Unicode 4.0:2003年4月
  • Unicode 4.0.1:2004年3月
  • Unicode 4.1:2005年3月
  • Unicode 5.0:2006年7月
  • Unicode 5.1:2008年4月
  • Unicode 5.2:2009年10月
  • Unicode 6.0:2010年10月
  • Unicode 4.1:2005年3月
  • Unicode 6.1:2012年1月31日
  • Unicode 6.2:2012年9月

ISO/IEC 8859

 

ISO/IEC小组在1984年成立后的第三年(即1987年)開始启动ISO 8859标准的编写,ISO 8859是一系列8位字符集的标准。主要为世界各地的不同语言(除CJK)而单独编写的字符集,一共定义了15个字符集:

 

  • ISO/IEC 8859-1:西欧语言
  • ISO/IEC 8859-2  :中欧语言
  • ISO/IEC 8859-3 :南欧语言
  • ISO/IEC 8859-4: 北欧语言
  • ISO/IEC 8859-5: 斯拉夫语
  • ISO/IEC 8859-6: 阿拉伯语
  • ISO/IEC 8859-7:希腊语
  • ISO/IEC 8859-8:希伯来语
  • ISO/IEC 8859-9:土耳其语
  • ISO/IEC 8859-10: 北日耳曼语
  • ISO/IEC 8859-11:泰语
  • ISO/IEC 8859-13: 波罗的语族
  • ISO/IEC 8859-14: 凯尔特语族
  • ISO/IEC 8859-15:西欧语言。收录芬兰语字母和大写法语重音字母,以及欧元(€)符号
  • ISO/IEC 8859-16 :东南欧语言,主要供罗马尼亚语使用,并增加欧元(€)符号

当中ISO/IEC 8859-1至ISO/IEC 8859-4四个项目早在1982年就已经编写出来,仅仅只是是由ANSI与ECMA合作完毕,并于1985年正式发布。ISO/IEC小组成立后。这一成果被其收录。并改名为ISO/IEC 8859 前四个项目。

大家事实上发现以上15个字符集中并没有代号为“ISO/IEC 8859 -12”的字符集。据说-12号本来是预留给印度天城体梵文的,但后来却搁置了(阿三有了自己的编码-ISCII)。因为英语没有不论什么重音字母。故可使用以上十五个字符集中的不论什么一个来表示。

 

 ISO/IEC 10646 / UCS

 

1993年,ISO/IEC 10646标准第一次发表,ISO/IEC 10646是ISO 646的扩展,定义了1个31位的字符集。ISO 10646标准中定义的字符集为UCS,UCS是Universal Character Set的缩写。中文译作通用字符集。

 

版本号:

 

  • ISO/IEC 10646-1:第一次发表于1993年,如今的公开版本号是2000年发表的ISO/IEC 10646-1:2000。

 

  • ISO/IEC 10646-2:在2001年发表。

 

包括字符:

 

最初的ISO 10646-1:1993的编码标准。即Unicode 1.1。收录中国大陆、台湾、日本及韩国通用字符集的汉字共计20,902个,当然每一个版本号的Unicode标准的字符集所包括的字符数不尽同样。UCS包括了已知语言的全部字符,除了拉丁语、希腊语、斯拉夫语、希伯来语、阿拉伯语、亚美尼亚语、格鲁吉亚语,还包括中文、日文、韩文这种方块文字,此外还包括了大量的图形、印刷、数学、科学符号。 UCS给每一个字符分配一个唯一的代码,而且赋予了一个正式的名字,通常在表示一个Unicode值的十六进制数的前面加上“U+”,比如“U+0041”代表字符“A”。

 

编码方案:

 

UCS不过一个超大的字符集。关于UCS制定的编码方案有两种:UCS-2UCS-4,Unicode默认以UCS-2编码。

顾名思义。UCS-2就是用两个字节编码,UCS-4就是用4个字节(实际上只用了31位,最高位必须为0)编码。

那么UCS-2事实上能够容纳的字符数为65536(2的16次方),而UCS-4能够容纳的字符数为2147483648(2的31次方)。

事实上对于UCS-2已经是全然够用了,基本能够包括世界全部国家的经常使用文字,假设须要考虑一些偏僻字,那么UCS-4则绝对能够满足了,21亿个字符哪怕是整个宇宙也够用了吧!

 

UTF

 

Unicode 诞生。随之而来的计算机网络也发展了起来。Unicode 怎样在网络上传输也是一个必须考虑的问题,于是在1992年,面向网络传输的UTF标准出现了。 UTF是UnicodeTransformation Format的缩写。中文译作Unicode转换格式。

事实上我们从如今能够把Unicode看作是一个标准或组织,而UCS就是一个字符集。那么UCS在网络中的传输标准就是UTF了。 前面提到了UCS的编码实现方式为UCS-2和UCS-4,即要么是每一个字符为2个字节。要么是4个字节。假设一个仅包括基本7位ASCII字符的Unicode文件,每一个字符都使用2字节的原Unicode编码传输,其第一字节的8位始终为0,这就造成了比較大的浪费。可是,聪明的人们发明了UTF-8,UTF-8採用可变字节编码。这样能够大大节省带宽。并添加网络传输效率。

 

UTF-8

 

使用1~4个字节为每一个UCS中的字符编码:

 

  • 128个ASCII字符仅仅需一个字节编码(Unicode范围由U+0000至U+007F)

 

  • 拉丁文、希腊文、西里尔字母、亚美尼亚语、希伯来文、阿拉伯文、叙利亚文及它拿字母须要二个字节编码(Unicode范围由U+0080至U+07FF)

 

  • 大部分国家的经常使用字(包含中文)使用三个字节编码

 

  • 其它极少使用的生僻字符使用四字节编码

 

UTF-16/UCS-2

 

UCS-2的父集。使用2个或4个字节来为每一个UCS中的字符编码:

 

  • 128个ASCII字符需两个字节编码

 

  • 其它字符使用四个字节编码

 

UTF-32/UCS-4

 

等同于UCS-4。对于全部字符都使用四个字节来编码

 

GB13000

 

前面提到了Unicode的迅速发展,至1993年时。包括CJK的Unicode 1.1已经公布了,天朝的ZF也意识到了须要一个更大的字符集来走向世界。于是在同一年,中国大陆制定了差点儿等同于Unicode1.1的GB13000.1-93国家编码标准(简称GB13000)。是的,你没听错,中华人民共和国信息产业部把Unicode里的全部东东拿过来,然后自己又一次修订公布了下。改为了国家标准GB13000。

此标准等同于 ISO/IEC 10646.1:1993和Unicode 1.1。

 

GBK

 

1995年,在GB13000诞生后不久。中国教育科研网(NCFC)与美国NCFnet直接联网,这一天是中国被国际承觉得開始有网际网路的时间。此后网络正式開始在中国大陆接通,个人计算机開始在中国流行,尽管当时仅仅是高富帅才消费得起的产品。中国是一个十几亿人口的大国,微软意识到了中国是一个巨大的市场。当时的微软也将自己的操作系统市场布局进中国,进入中国随之而来要解决的就是系统的编码兼容问题。

之前的国家编码标准GB 2312,基本满足了汉字的计算机处理须要。它所收录的汉字已经覆盖中国大陆99.75%的使用频率。但对于人名、古汉语等方面出现的罕用字和繁体字。GB 2312不能处理,因此微软利用了GB2312中未使用的编码空间,收录了GB13000中的全部字符制定了汉字内码扩展规范GBK(K为汉语拼音 Kuo Zhan中“扩”字的首字母)。所以这一关系事实上是大陆把Unicode1.1借鉴过来改名为了GB13000。而微软则利用GB2312中未使用的编码空间收录GB13000制定了GBK。所以GBK是向下全然兼容GB2312的。

 

包括字符:

 

共收录21886个字符, 当中汉字21003个, 字符883个

 

编码方式:

 

GBK仅仅只是是把GB2312中未使用的空间。编码了其它字符,所以GBK相同是用两个字节为每一个字符进行编码。

 

GB18030

 

微软到了99年前后。说GBK已经落伍了,如今流行UTF-8标准,准备全盘转换成UTF-8,但中国ZF不是吃素的,编写并强制推出了GB18030标准。GB18030的诞生另一个原因是GBK仅仅包括了大部分的汉字和繁体字等。我们的少数民族兄弟根本木有考虑!中国有56个民族,当中有12个民族有自己的文字,那怎么办呢?在2000年。电子工业标准化研究所起草了GB18030标准,项目代号“GB 18030-2000”,全称《信息技术-信息交换用汉字编码字符集-基本集的扩充》。此标准推出后。在中国大陆之后的所售产品必须强制支持GB18030标准,不然不得卖。(这招挺狠的 - -#)

 以上是关于字符编码的前世今生的主要内容,如果未能解决你的问题,请参考以下文章

字符编码的前世今生--转

字符编码的前世今生(Unicode,UTF, GB2312)

计算机字符编码的前世今生

(二)base64编码的前世今生

Python 编码的前世今生

第四节:乱码的前世今生——字符集和比较规则