由于计算机只能存储和处理二进制的“0”和“1”,无法处理其他的字母、数字和符号,所以就需要有某种东西来达到类似桥梁的作用——例如图1-7中的ASCII——通过它,人们就可以看懂用计算机表示字母、数字或其他符号。
人们能够想到的最直接的方法是就是对字母进行编号,例如A为1,B为2,C为3等。著名英国作家弗朗西斯·培根(Francis Bacon)曾用五位序列来编码英文的26个字母,在十六世纪用来传递密信。
如果以二进制来表示25(2的5次方,5位)也就是32,可以存32个字母,对于26个英文字母来说是足够用了。但它无法区分大小写字母,也无法再区分数字和标点符号。因此就有了ASCII(American Standard Code for Information Interchange,美国信息交换标准代码)。
标准的ASCII码发明于1963年,但1967年才第一次发表,1986年则作了最后一次更新,目前ASCII包含27(2的7次方,也就是128)个字符。这个128个字符用来表示大小写字母、数字0~9、标点符号、以及像“#”、“@”、“)”、“\r”(回车)、“\n”换行、“\t”(制表)等这样的特殊符号,如图1-12所示。
图1-12 标准ASCII码表
因为ASCII诞生的年代较早,所以使用非常广泛,使得不同的组织、不同的计算机之间能够互相交换数据与信息。但它也有个尴尬的限制:ASCII只为印欧语系日耳曼语族中的英语所设计,甚至都不兼容同一语系同一语族下的德语、荷语等其他语种。好在当初设计二进制的时候规定1个字节(Byte)由8位(Bit)二进制数组成,因此ASCII也就顺理成章地由7位扩展为8位(2的8次方),也就是扩展后ASCII有256个字符,又叫Extended ASCII(扩展ASCII,简称为EASCII)。
但EASCII由于国际化和标准化程度不够,所以就被设计更为优良的ISO/IEC 8859字符编码方案取代了。不过,即使是ISO/IEC 8859依然只是使用了单个字节,即8位来表示字符集,所以ASCII、EASCII和ISO/IEC 8859统称为单字节字符集(SBCS),而且ISO/IEC 8859也只能表示欧洲各国所使用到的字符,所以范围依然很有限。
当计算机在世界范围内的应用越来越广泛时,单字节字符集就已经完全无法使用了,因为仅仅中文常用汉字就有几千个,还不包括各种非常用字、生僻字。除此之外,每家计算机制造商、大的软件厂商也都发布自己的字符集。例如ASMO-708、DOS-720、Windows-1250、IBM EBCDIC等。这些字符集统称为多字节字符集(MBCS)。
为了解决这种“一锅粥”式的混乱局面,1992年,Unicode出现了。它为每种语言的每个字符设定了一个唯一的二进制编码,以满足跨语言跨平台的文本转换、处理要求。Unicode使用4字节共32位,也就是232个字符来填充字符集。Unicode本身只是一个字符集标准,针对它的实现称为UTF(Unicode Transformation Format,Unicode格式转换)。
顺便说一句,实际开发中使用UTF-8时有几个地方需要注意:
1. “UTF-8”是标准写法,因为Windows不区分大小写,所以写成“utf-8”也行。也可以把中间的“-”省略,写成“UTF8”;
2. 在MySQL的配置文件中只能使用“utf8”,如果写成“utf-8”或者“UTF-8”都不会生效;
3. 对于MySQL来说,“utf8mb4”才是真正意义上的“utf8”,因为低版本的MySQL中“utf8”最大字符长度为3字节,遇到表情之类的特殊字符就会出错。
由于Unicode的实现细节较为复杂,且了解这些对开发帮助不大,故无需深究。只需要知道:如果收发双方的计算机使用的都是Unicode编码,那么是绝不会出现乱码现象的。发出的内容是什么,收到的内容就是什么,也不会出现类似“???”、“锟斤拷”、“�”等莫名其妙的字符。