编程语言与计算机中的字符编码(ASCII和Unicode)

笔者学习计算机的时候,经常会遇到与字符编码相关的问题,所以为了方便查询,就对常见字符编码的来源,分类,内容等做了一下总结。笔者先简单写一部分,等后续遇到问题的时候再慢慢完善吧。
笔者在查询相关资料的时候发现与字符编码相关的内容太多了,所以就只列出主要框架,具体的细节就不深究了(想看细节的可以看看笔者贴出的参考文献)。


概述

许多年以来,多数编程语言都使用一种名为ASCII(American Standard Code for Information Interchange)的标准,在计算机内部表示字符,这种标准包括128个字符,足够表示英语中经常出现的特殊字符。但如果去表示世界上所有语言中的字符和符号,就远远不够啦。
所以人们逐渐转向了Unicode标准。Unicode标准是一个字符编码系统,支持数字化处理和所有语言的书面文本显示。目前Unicode标准中的字符超过120000个,覆盖了129种从古至今的语言和符号集合。
而Unicode标准可以通过各种内部字符编码来实现。现在万维网上用于实现Unicode标准最常使用的字符编码是UTF-8。

历史

ASCII标准是从电报代码开始开发的。它的第一个商业用途是作为一个七位 电传贝尔数据业务推广代码。
关于ASCII标准的制订工作始于1960年10月6日,美国标准协会(ASA)(现为美国国家标准协会或ANSI)X3.2小组委员会的第一次会议。
该标准的第一版于1963年出版,于1967年进行了重大修订,并经历了1986年的最新更新。与早期的电报代码相比,所提出的贝尔代码和ASCII都被排序,以便更方便地对列表进行排序(即字母化),并为除电传打印机之外的设备增加功能。
编程语言与计算机中的字符编码(ASCII和Unicode)_第1张图片
早于1972年的打印机手册中的ASCII,图来自ASCII的维基百科
最初的ASCII基于英文字母,将128个指定字符编码为7位整数,如上面的ASCII图所示。其中95个编码字符是可打印的:这些字符包括数字0到9,小写字母a到z,大写字母A到Z,以及标点符号。此外,原始的ASCII规范包括33个非打印控制代码,这些代码源自Teletype机器 ; 但是其中大部分已经过时,现在仅有一些常用,例如回车,换行和Tap。

ASCII标准最初是美国国家标准,供不同计算机在相互通信时用作共同遵守的西文字符编码标准,它已被国际标准化组织(International Organizationfor Standardization,ISO)定为国际标准,称为ISO 646标准,适用于所有拉丁文字字母。ISO / IEC 646是一组ISO标准的名称,描述为信息技术 - 用于信息交换的ISO 7位编码字符集,至少自1964年以来与ASCII合作开发。第一版在1967年完成。

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

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

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

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

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

Unicode标准于1990年开始研发,1994年正式公布。随着计算机工作能力的增强,Unicode也在面世以来的十多年里得到普及。
Unicode 11.0版已发布(2018年6月5日)。在Unicode联盟网站上可以查看完整的11.0的核心规范。
Unicode定义了大到足以代表人类所有可读字符的字符集。

ASCII

ASCII 码使用指定的7 位或8 位二进制数组合来表示128 或256 种可能的字符。标准ASCII 码也叫基础ASCII码,使用7 位二进制数(剩下的1位二进制为0)来表示所有的大写和小写字母,数字0 到9、标点符号, 以及在美式英语中使用的特殊控制字符。其中:
0~31及127(共33个)是控制字符或通信专用字符(其余为可显示字符),如控制符:LF(换行)、CR(回车)、FF(换页)、DEL(删除)、BS(退格)、BEL(响铃)等;通信专用字符:SOH(文头)、EOT(文尾)、ACK(确认)等;ASCII值为8、9、10 和13 分别转换为退格、制表、换行和回车字符。它们并没有特定的图形显示,但会依不同的应用程序,而对文本显示有不同的影响。
32~126(共95个)是字符(32是空格),其中48~57为0到9十个阿拉伯数字。
65~90为26个大写英文字母,97~122号为26个小写英文字母,其余为一些标点符号、运算符号等。
同时还要注意,在标准ASCII中,其最高位(b7)用作奇偶校验位。所谓奇偶校验,是指在代码传送过程中用来检验是否出现错误的一种方法,一般分奇校验和偶校验两种。奇校验规定:正确的代码一个字节中1的个数必须是奇数,若非奇数,则在最高位b7添1;偶校验规定:正确的代码一个字节中1的个数必须是偶数,若非偶数,则在最高位b7添1。
后128个称为扩展ASCII码。许多基于x86的系统都支持使用扩展(或“高”)ASCII。扩展ASCII 码允许将每个字符的第8 位用于确定附加的128 个特殊符号字符、外来语字母和图形符号。

Unicode

Unicode是国际组织制定的可以容纳世界上所有文字和符号的字符编码方案,
最初的unicode编码是固定长度的,16位,也就是2两个字节代表一个字符,这样一共可以表示65536个字符。显然,这样要表示各种语言中所有的字符是远远不够的。Unicode4.0规范考虑到了这种情况,定义了一组附加字符编码,附加字符编码采用2个16位来表示,这样最多可以定义1048576个附加字符,目前unicode4.0只定义了45960个附加字符。

Unicode只是一个编码规范,目前已经实现并流行的unicode编码主要有三种:UTF-8,UCS-2(是UTF-16的低配版)和UTF-16,三种unicode字符集之间可以按照规范进行转换。此外UTF-32应该有部分应用了。

Unicode可容纳的字符总数为17*65536=1114112个,但目前实际应用到的只是其中的一小部分。请注意,这是个编码方案(或者说编码标准),它为世界上目前已存在的所有文字和符号以及将来可能出现的字符都指定(或者说预留)了一个唯一的数字编码,但它并不是具体的实施方式,也就是说Unicode中的数字编码和电脑上的文字编码是不能直接划等号的,UTF-8、UTF-16和UTF-32才是具体的实施方式,其中UTF-8用8位的倍数来表示一个字符,也就是说在UTF-8编码格式中,一个字符可以是8位(一个字节)、16位(两个字节)、24位(三个字节)、32位(四个字节),同理,UTF-16则可以是16位(两个字节)、32位(四个字节),而UTF-32则所有字符都是32位(即四个字节)的。事实上,用三个字节表示一个字符的容量(16777216)已经远远超过Unicode标准中的最大容量(1114112)了。

引用

[1]ASCII,百度百科,https://baike.baidu.com/item/ASCII/309296
[2]Unicode,百度百科,https://baike.baidu.com/item/Unicode/750500
[3]彻底弄懂 Unicode 编码,https://blog.whezh.com/encoded/
[4]ASCII,wikipedia,https://en.wikipedia.org/wiki/ASCII
[5]ISO / IEC 646,wikipedia,https://en.wikipedia.org/wiki/ISO/IEC_646
[6]UNICODE容纳65536 个字符,怎么装得下9万多汉字的?百度知道,https://zhidao.baidu.com/question/1707536489961769300.html
[7]Unicode字符集中最大允许有多少字符?目前已经定义了多少个字符? 百度知道,https://zhidao.baidu.com/question/483675784.html
[8]python编程导论第二版,John V.Guttag著,陈光欣译
[9]UTF-8 GBK UTF8 GB2312之间的区别和关系 http://www.divcss5.com/html/h53.shtml

你可能感兴趣的:(编程语言,字符编码,ASCII,Unicode,UTF-8)