1 ASCII
其实计算机处理字符串的方法都是一样的——一串字节序列,每个字节或者每几个字节代表了现实世界里的一个字符。至于什么字节代表什么字符,就由不同的编码标准来指定了。其中最常见的就是人们耳熟能详的ASCII——由7位二进制数据表示一个字符(一个字节是8位二进制数据)。
2 扩展ASCII
后来,人们开始扩展ASCII,多用一位二进制数据可以用来表示128个额外的字符。当时IBM PC在1981年推出的时候,其中有一个基于ROM的256个字符组成的字符集被用在了他们的显卡里,而这个刚好就成为了IBM公司标准的一个重要组成部分。这个IBM扩展字符集被烧录在无数显卡和打印机的ROM里,被很多软件用来扩展自己的字符显示能力。
1985年Windows 1.0发布的时候,微软发布了ANSI字符集,因为它是基于ANSI标准和ISO标准的一个草案。和扩展的ASCII一样,ANSI字符集仍然是一个字节来表示一个字符,但微软希望用这个标准取代IBM的扩展ASCII成为系统的主要编码方式。
3 代码页(Code Page)
最恐怖的事情发生了——1987年4月,MS-DOS3.3把代码页的概念介绍给了IBM PC用户,每个代码页都是一个字符集,并且这一概念也被后来用到了Windows系统里(这里可能有所争议,代码页的概念在有些地方据说是IBM先提出的,后来被Windows引用,然而历史的问题就让大家自己去考证吧~)。这样一来,原本的IBM字符集被成为第437页代码页。当时微软自己的MS-DOS Latin 1字符集成为了第850页代码页,然后其他的代码页就是为其他语言制定的了,较低的128个代码(7位)总是表示的是标准ASCII的字符,而较高的128个代码取决于定义代码页的语言。
代码页的数量以超乎想象的速度递增,后来更是出现了不同操作系统对于同一个国家语言的代码页居然互相不兼容的情况,每个计算机环境的代码页都对标准字符集进行了修订,这使得局面更加混乱。
4 双字节字符集(DBCS,有的时候也可以称为多字节字符集MBCS)
等等,我们是不是忘记了中文?没错,单字节字符肯定远远包含不了上万个字符的语言,例如中文。因此这些国家都开发出了表示自己本国文字的双字节字符集,顾名思义就是用2个字节(16位二进制数据)表示ASCII以外的字符,其中我们最常见就是我国的GB系列编码了(GB其实就是国标的拼音缩写 )。这些不同国家创造出来了的字符集,虽说与ASCII兼容,但不同国家的编码互相是不兼容的,例如同样的两个字节,在中文里和日语里可能就会是两个不同的字符。而这些不同国家的字符集,同样也被微软纳入了代码页体系中,例如中文就是第936页代码页(我们最常见的CP936就是这个意思,因此它表达的字符集和GBK是一样的)。
特别值得一提的是,Windows支持四种不同的双字节字符集:代码页932(日文)、936(简体中文)、949(韩文)以及950(繁体中文)。双字节字符集(DBCS)只有在为这些国家制造的Windows版本上才被支持。[1]
5 Unicode
Unicode是1988年由Apple和Xerox共同建立的一项标准[2]。Unicode的诞生解决了双字节字符集的混乱问题:虽然同样是用16位(2个字节)表示字符,但它只有一个字符集,包含了世界上任何一个国家使用的语言所用的字符。而相对于传统C语言的char类型(1个字节),我们可以称Unicode为宽字符。上文提到的DBCS(MBCS)和Unicode都属于宽字符。
尽管一个Unicode编码确实是一份字符集,包含了世界上所有文字和符号,但Unicode毕竟只是一个标准,需要人们去实现。Unicode标准中定义了3种编码(实现)方式:UTF-8, UTF-16, UTF-32。除此之外也产生了其他一些Unicode的编码方式。而现在使用最多的是实现方式是:UTF-8, UTF-16和UCS-2(UTF-16的一个子集)。而不太常用的UTF-32(也可以写作UCS-4)[3],因为用了4个字节做编码,因此效率很低。另外,Unicode的实现还有大小端(Big Endian 和 Small Endian)的区别,并且UTF-8还存在有是否带有BOM标记的问题,因此在很多文本编辑器里关于Unicode这一项的编码转换都会有很多种。
说到这里,关于计算机字符编码的解释就到此为止了。后面的章节将会描述字符编码在编程语言以及操作系统内核中究竟是有什么样的区别,从而解答最开始我们提到的那个Python的问题。
参考文献:
[1] Charles Petzold 《Windows程序设计 第5版》方敏, 张胜, 梁路平, 赵勇 等 译 清华大学出版社
[2] Jeffrey Richter, Christophe Nasarre 《Windows核心编程 第5版》葛子昂, 周靖, 廖敏 译 清华大学出版社
[3] en.wikipedia.org/wiki/Unicod… 来自维基百科对于Unicode
这一词条的解释