计算机内部,所有信息最终都是一个二进制值,称为一个bit。八个 bit 组成一个字节(byte)。一个字节一共可以表示256种不同的状态。
但二进制数据是不可读的,如何用二进制的数据来表示我们生活中的字符(A、B、C等),就是字符编码要解决的问题。
1.ASCII码
第一代计算机发明的时候,美国国家标准协会ANSI(American National Standard Institution)收集了当时美国所使用的所有字符(一共128个),采用一个字节的低7位(最高位为0)来进行编码。含有如下字符:
- 33个终端控制字符。
- 10个数字
- 26个大写字母
- 26个小写字母
- 33个符号
这套编码方案称之为:ASCII码(American Standard Code for Information Interchange,美国信息互换标准代码)。
2.ASCII扩展码
但随着计算机技术发展,一些不使用英文的发达国家也开始使用了计算机,他们的字母里有许多是ASCII里没有的。于是他们利用一个ASCII在单个字节中最高位为1的128个编码来满足自己的特定需求。称为扩展 ASCII 码。
扩展ASCII码能基本能满足没过及西方发达国家的需求,因为一个字节就完全够用了。
3.MBCS(ANSI)多字节编码
后来世界各个地也用上了计算机。而这些国家的语言字符不止256个,比如中文,常用汉字就有6000多个。一个字节显然无法满足需求了。于是出现了多字节编码MBCS(Muilti-Bytes Charecter Set),也称为ANSI编码。使用多个字节来代表一个字符。
比如中文的ANSI为gb2312、日本为JIS。
4.GB编码
4.1 GB2312编码
GB2312规定小于127的字符的意义与原来相同,但两个大于127的字符连在一起时,就表示一个汉字。在这些编码里,还把数学符号、罗马希腊的字母、日文的假名都编进去了,连在 ASCII 里本来就有的数字、标点、字母都统统重新编了两个字节长的编码,这就是常说的”全角”字符,而原来在127号以下的那些就叫”半角”字符了。
但GB2312并没有用满127*127个编码。第一个字节用了87个(161-247),第二个字节用了94个(161-254)。
4.2 GBK编码
后来还是不够用,于是不再要求第二个字节一定是大于127的,只要第一个字节是大于127就固定表示这是一个双字节汉字的开始。扩展之后的编码方案被称为 GBK 标准,GBK 包括了 GB2312 的所有内容,同时又增加了近20000个新的汉字(包括繁体字)和符号。
5.Unicode
ANSI编码有个缺点,就是不同的语言体系中同一个编码值代表不同的字符。这催生了Unicode的诞生。Unicode为全世界所有国家下的每一个字符规定了一个独一无二的值,共1114112=65536*17个。
注意这里Unicode并没有说是编码,实际上Unicode只是字符集,规定每个字符的二进制代码。
5.1 UTF-32和USC-4
由于Unicode有 1114112个值,至少需要三个字节来存储。UTF-32和USC-4都采用4个字节的定长编码方式来存储。
5.2 UTF-16和USC-2
USC-2使用2个字节来存储Unicode中最常用的一部分编码。是定长编码。
UTF-16使用2个字节存储Unicode中最常用的一部分编码,其它一部分使用4个字节存储,是变长编码。
5.3 UTF-8
UTF-8是互联网上使用最广的一种 Unicode 的实现方式。采用变长编码。
UTF-8的编码规则很简单:
- 对于单字节的符号,字节的第一位设为0,后面7位为这个符号的unicode码。因此对于英语字母,UTF-8编码和ASCII码是相同的。
- 对于n字节的符号(n>1),第一个字节的前n位都设为1,第n+1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的unicode码。下表总结了编码规则,字母x表示可用编码的位。