1.3 Unicode字符发展历史
早期的计算机仅用于科学计算,后来的计算机被要求能够进行字符处理和表示,ASCII被创造出来。ASCII使用7位(bit)来表示一个字符,共能够表示128个字符,包含了控制码(如换行符“\n”等)、符号(如“?”“!”等)、数字(0~9)和26个英文字母(包括大小写,即a~z和A~Z)。后来ASCII进行了扩充,使用8位来表示一个字符,新增了128个字符。
当计算机普及到全世界时,各个国家面临的首要问题就是如何针对自己国家的语言制定一套自己国家的编码规范。为此,我国提出了针对中文的编码方式(GB 2312),这套编码方式基于ASCII(并非ASCII的扩充版本),使用2个字节来表示一个汉字。具体的方式是前127个字符不变,当第1个字节(高字节)大于127时,表示一个汉字的开始,再用这个字节和第2个字节(低字节)的组合来表示一个汉字。在这套编码方式中,不仅把中文编进来了,还把一些数学符号、罗马希腊字母和日本假名等都编进来了,也把ASCII中原有的26个英文字母和符号也都编进来了(当然这些字母是以2个字节表示的,为了和ASCII中原有的字母区别开来,前者称为全角字符,后者称为半角字符)。
类似于我国的编码方式,其他国家和地区也制定了自己的编码方式,如日本的Shift_JIS等。种类繁多的编码方式容易引起解码的混乱,而且编码方式之间也没有简易的算法进行转换,这大大影响和阻碍了各个国家及地区之间的交流。
为了统一全世界的编码方式,提出了Unicode编码方式。Unicode制定了一种新的编码方式,这种编码方式将全世界的字符放在一张表内。Unicode是废除了所有的地区性编码方式而重新制定的编码方式,而不是简单地从ASCII继承过来的(但前128个字符仍保留为ASCII字符)。
虽然Unicode为全世界的字符提供了一个唯一的编码,但并没有规定如何在计算机中存储这些编码,根据Unicode编码方式来制定的具体实施方案有UTF8、UTF16以及UTF32,这些实施方案规定了如何在计算机中存储和表示编码。
对于Unicode中的字符,需要使用2个字节(16位)至4个字节(32位)来存储其编码。不过对于各国常用的字符,2个字节就能存储其编码,因此通常使用2个字节的UTF16就足够了。UTF是Unicode Transformation Format的缩写,意为Unicode转换格式。对于欧美的一些国家而言,常用的还是英文字母,如果使用UTF16,就会浪费很多存储空间,因此产生了UTF8,它是一种变长编码方式,使用8位来存储Unicode中的所有编码。计算机中的程序逐个字节地来读取Unicode编码,根据每个字节中开头的标志来决定把1个、2个、3个或4个字节作为1个编码来处理。
UTF8的一个最大特点是它是一种变长的编码方式,它可以使用1~4个字节来表示一个字符,可根据不同的字符来改变编码的长度。当字符是ASCII中的字符时,就用1个字节来表示,将ASCII中的字符作为UFT8的一部分。需要注意的是:在Unicode中,一个中文字符占用2个字节;而在UTF8中,一个中文字符占用3个字节。从Unicode到UTF8的转换并不是直接对应的,需要利用一些算法和规则来进行转换。Unicode到UTF8的转换如表1-1所示。
表1-1 Unicode到UTF8的转换
注:x表示任意bit。
0xxxxxxx:将以0开头的1个字节当成1个编码,和ASCII完全一样。
110xxxxx 10xxxxxx:如果采用这种格式,则把2个字节当成1个编码。
1110xxxx 10xxxxxx 10xxxxxx:如果采用这种格式,则把3个字节当成1个编码。
UTF8需要判断每个字节中的开头标志,如果某个字节在传输过程中出错了,就会导致后面的字节在解析时出错。UTF8在网络传输中的应用十分普及。