字符编码
英文字符编码
SCII编码:用8位二进制进行编码,用于表示控制字符、英文字符、数字字符。因为使用8位二进制编码,所以ASCII编码只能表示256个字符,编号范围为0~255。在英文世界中,使用26个字母就可以拼写出全部的英文单词,每个字字母就是一个字符,所以,用8位的ASCII码就可以对整个英文世界进行编码。
中文编码
1. GB2312标准
GB2312总共覆盖了6763个常用汉字,GB2312标准把ASCII码表127号之后的扩展字符集去掉,并规定,小于127(0x7F)的编码按照ASCII标准进行解码,当出现连续两个大于127(0x7F)的编码时,这两个连续的大于0x7F的编码表示一个汉字,第一二个字节都是用0xA1~0xFE进行编码。其中,ASCII码中原有的数字字符、英文字符、标点等称为半角字符,大于0x7F的相应字符编码称为全角字符。
GB2312解码规则: 当使用GB2312编码标准时,给定一串字符编码,按照字节进行检测,首先检测每个字节的大小,如果字节值小于0x7F,就用ASCII标准解码,如果连续两个字节的值都大于0x7F,就把这两个字节视为一个整体,使用GB2312标准解码。
eg: 0x61 0xB0 0xA1 0x61
a 啊 a
从第一个字节开始检测,0x61小于0x7F,用ASCII标准解码,它表示英文字符“a”,第二个字节0xB0大于0x7F,
第三个字节0xA1大于0x7F,连续两个字节大于0x7F,把它们连为一体使用GB2312解码为中文字符“啊”,
第四个字节0x61小于0x7F,用ASCII标准解码,它表示英文字符“a”。
2. GBK编码
GBK编码在GB2312的基础上又增加了14240个汉字、生僻字和符号。按照GB2312的编码方式,两个字节已经不够用了,这时,GBK编码制定了新的标准:只要出现一个大于0x7F的字节,那么这个字节和它后面一个字节共两个字节就表示一个汉字(GB2312规定两个字节都大于0x7F才表示一个汉字),这样做的好处就是,GBK编码兼容了ASCII编码和GB2312编码。
GBK解码规则:当使用GB2312编码标准时,给定一串字符编码,按照字节进行检测,首先检测每个字节的大小,如果字节值小于0x7F,就用ASCII标准解码,如果遇到一个大于0x7F的字节,就把该字节和它后面一个字节连在一起用GBK标准进行解码,然后从第三个字节开始继续遍历检测。
eg: 0x61 0xB0 0x56 0x62
a 癡(chi) b
从第一个字节开始检测,0x61小于0x7F,用ASCII标准解码,它表示英文字符“a”,第二个字节0xB0大于0x7F,
那么就把0xB0、0x56连在一起用GBK标准解码,然后从0x62开始继续检测
Unicode字符集
每个国家和地区都有一套自己的文字,不同的文字系统就要使用不同的编码标准,这就出现这样一个问题,同一个二进制编码在不同的编码标准中可能代表了不同的字符,比如0xB0A1,在GBK编码标准中为“啊”,而在Big5编码标准中就不是这个字了。这样,各个编码标准之间的不兼容就导致使用起来非常不方便。国际标准化组织ISO,将全球所有的语言所使用的字母、符号、文字进行统一编号,每个字符指定唯一一个标号与之对应(ASCII码编号不变),字符的编号从0x000000~0x10FFFF,该编号集称为Universal Multiple-Octet coded Character Set,简称UCS,一般也叫做Unicode。Unicode字符集仅仅是对所有字符进行了编号,并没有指定这些编号的编码规则,所以,后来才出现了各种Unicode的编码规则Unicode Transformation Format,典型的Unicode编码规则如UTF-8,UTF-16,UTF-32等。
1. UTF-32
Unicode Transformation Format 32,用32位(4字节)对Unicode字符集进行编码。编码时,Unicode字符集中的每一个字符都用4字节表示,直接把字符对应的Unicode编号转换为二进制数进行存储。而正因为UTF-32用4字节为每个字符编码,所以,UTF-32不兼容ASCII编码,使用ASCII编码标准写的程序,通过UTF-32编码方式打开会显示乱码。
解码时,直接按四个字节检测,编码与Unicode标号一一对应。
字符:A ---> ASCII编码:0x41 ---> Unicode编号:0x0000 0041 ---> UTF-32编码:0x0000 0041
字符:啊 ---> GBK编码:0xB0A1 ---> Unicode编号:0x0000 554A ---> UTF-32编码:0x0000 554A
2. UTF-16
Unicode Transformation Format 16,用16位(2字节)或32位(4字节)对Unicode字符集进行编码。对Unicode字符编号在0 ~ 65535的字符使用2字节编码,将每个字符的编号直接转换为2字节的二进制数0x0000 ~ 0xFFFF。而Unicode字符集在0xD800 ~ 0xDBFF区间内的编号不表示任何字符,UTF-16用这段编号与Unicode字符集中大于0xFFFF的字符编号进行映射,得到扩展的4字节编码。UTF-16也不兼容ASCII编码。
UTF-16解码时,按两个字节去检测,如果这两个字节都不在0xD8000xDFFF之间,就说明是双字节编码的字符,使用双字节解码;如果这两个字节在0xD8000xDFFF之间,说明是4字节编码的字符,以4字节解码。
2. UTF-8
Unicode Transformation Format 8,用1,2,3,4个字节对Unicode字符集进行编码,每个字符根据自己的编号范围进行相应编码。它的编码规则是这样的:
对于UTF-8单字节的编码,该字节最高位设为0,剩余位填入字符的Unicode编号,对于Unicode编号在0x00000000 ~ 0x0000007F的字符,UTF-8编码只要一个字节,兼容ASCII编码。对于N字节的编码,第一字节最高位开始,前N位置为1,第N+1位设0,剩余字节最高位设为10,这N个字节的其余空位填充该字符的Unicode编号,高位补0。具体可见下表:
Unicode编号 UTF-8编码
第1字节 第2字节 第3字节 第4字节
0x00000000~0x0000007F 0xxx xxxx
0x00000080~0x000007FF 110x xxxx 10xx xxxx
0x00000800~0x0000FFF 1110xxxx 10xx xxxx 10xx xxxx
0x00010000~0x0010FFFF 1111 0xxx 10xx xxxx 10xx xxxx 10xx xxxx
解码时,看第一个字节;0开头:单字节解码; 110开头:双字节解码; 1110开头:三字节解码; 11110开头:四字节解码; UTF-8编码的时候,汉字一般是占三个字节的。