ASCII
在计算机内部,所有信息最终表示成一个二进制的编码。每个二进制位(bit)有0和1两种状态,一个字节(byte)有8个二进制位,可以组合成256种状态,从00000000到11111111。
上个世纪60年代,美国制定了一套字符编码,对英语字符和二进制位之间的关系做了统一规定,称为ASCII码。ASCII码一共规定了128个字符的编码,只占用了一个字节的后面7位,最前面的1位统一规定为0,比如空格”SPACE”是32。
非ASCII编码
英语中用128个符号编码就够了,但是对于其他语言,128个符号是不够的。因此一些欧洲国家利用字节中闲置的最高位编入新的符号,这样可以最多表示256个字符,例如法语中的e的编码为130.
对于亚洲文字,使用字符更多,一个字节只能表示256种符号不够,必须使用多个字符表达一个符号,比如简体中文常见的编码方式GB2312(GBK),使用两个字节表示一个汉字。这里需要注意,GB类的汉字编码与Unicode和UTF-8是毫无关系的。
Unicode
Unicode是为了解决传统的字符编码方案的局限产生的,为每种语言的每个字符设定了统一并且唯一的二进制编码,以满足跨平台,跨语言进行文本转换、处理的要求。但是没有规定这个二进制代码如何存储。比如汉字”严”是十六进制数4E25,转换成二进制数有15位,至少需要两个字节表示这个符号。
UTF-8
UTF-8是互联网上面使用最广的一种unicode的实现方式。UTF-8最大的一个特点,就是它是一种变长的编码方式。它可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度。UTF-8的编码规则只有两条:
- 对于单字节的符号,字节的第一位设为0,后面7位为这个符号的unicode码,对于英语字母,UTF-8编码和ASCII码是相同的。
- 对于n字节的符号(n > 1), 第一个字节的前n位都设为1,第n+1位设为0,后面字节的前两位都设为10。剩下的位作为这个符号的unicode码。
如下表所示:
Unicode符号范围(十六进制) | UTF-8编码方式 |
---|---|
0000 0000-0000 007F | 0xxxxxxx |
0000 0080-0000 07FF | 110xxxxx 10xxxxxx |
0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx |
0001 0800-0000 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx |
下面以汉字”严”为例,演示如何实现UTF-8编码:
已知”严”的unicode是4E25(100111000100101),需要三个字节,一次从后往前填入格式中x,多出的位补0,得到”严”的UTF-8编码是”11100100 10111000 10100101”,转换成十六进制就是E4B8A5。
Notepad中其他编码格式
- ANSI编码方式,对于英文文件是ASCII编码,对于简体中文文件是GB2312(也就是现在的GBK),繁体中文版采用的是Big5码。
- Unicode编码指的是UCS-2编码方式,直接用两个字节存入字符的Unicode码。采用little endian格式。
- Unicode big endian与little endian对应。
Little endian和Big endian
Unicode码可以采用UCS-2格式直接存储,以汉字”严”为例,存储的时候,如果4E在前,25在后,就是Big endian方式;25在前,4E在后就是Little endian方式。
题外话,这两个古怪的名称来自英国作家斯威夫特的《格列佛游记》。在该书中,小人国里爆发了内战,战争起因是人们争论,吃鸡蛋时究竟是从大头(Big-Endian)敲开还是从小头(Little-Endian)敲开。为了这件事情,前后爆发了六次战争,一个皇帝送了命,另一个皇帝丢了王位。