1、ANSI 多字节编码
最早时计算机只支持英文字符,都是用 ASCII(American Standard Code for Information Interchange,美国标准信息交换代码)编码,一个字母或符号只需要一个字节存储。微软针对本地化字符编码采用的就是用 ANSI(American National Standards Institute,美国国家标准学会)多字节编码方式,系统里的英文和符号就使用单字节的 ASCII(0x00~0x7f),而对于汉字之类的本地化字符编码,就采用 0x80~0xFF 范围内的多个字节来表示,这样既能兼容 ASCII ,又能正常使用本地化语言文字。
支持的汉字编码:http://www.fmddlmyy.cn/text24.html
2、Unicode 系列编码
ANSI 多字节编码解决了各种语言文字的本地化使用问题,也有它自己的缺陷:各地制定的编码标准只对自己的语言文字有效,而不同语言文字的编码都是冲突的,因为大家都用 0x80~0xFF 范围字节表示自己的语言文字,而不考虑别的语言文字如何编码,冲突在所难免。将一种编码放到另一种编码的系统中会出现乱码,因此国际组织制定了 Unicode 编码,这种字符编码是对全球语言统一分配编码区间,各种语言字符互相不冲突,都可以兼容使用。
Unicode 编码系统,可分为编码方式和实现方式两个层次。对于国际组织发布的 Unicode 编码标准,对应的就是编码方式,最常用的是 UCS-2(Universal Character Set 2),采用两字节编码一个字符。也有四字节编码方式 UCS-4。在编码实现的过程中,有些考虑兼容旧的单字节 ASCII 编码,有些不考虑兼容性;有些考虑双字节中哪个字节放在前面,哪个字节放在后面的问题,即 BOM(Byte Order Mark,字节顺序标记)的作用。因此诞生了多种国际码的实现方式,统称为 Unicode 转换格式(Unicode Transformation Format,UTF)。
Unicode 转换格式 | 说明 |
---|---|
UTF-8 | 灵活的变长编码,对于 ASCII 使用一个字节编码,其他本地化语言文字用多个字节编码,最长可以到 6 个字节编码一个字符。对于汉字,通常是 3 个字节表示一个汉字。这是 Unix/Linux 系统默认的字符编码。 |
UTF-16 | 兼容 UCS-2,一般都是两字节表示一个字符,对于超出两字节的国际码字符,使用一对两字节来表示。在存储时,按两个字节的排布顺 序,可以分为 UTF-16LE(Little Endian,小端字节序)和UTF-16BE(Big Endian,大端字节序),微软所说的 Unicode 默认就是 UTF-16LE。 |
UTF-32 | 同 UCS-4,因为用四个字节表示一个字符,所以不需要考虑扩展了。这种编码方式简单,但也特别浪费空间,所以应用很少。在存储时也分为 UTF-32BE 和 UTF-32LE,因为用得少,所以不用太关心这种编码格式。 |
Unicode通常用两个字节表示一个字符,原有的英文编码从单字节变成双字节,只需要把高字节全部填为0就可以。
2.1 UTF-8以字节为单位对Unicode进行编码
从Unicode到UTF-8的编码方式如下:
UTF-8的特点是对不同范围的字符使用不同长度的编码。对于0x00-0x7F之间的字符,UTF-8编码与ASCII编码完全相同。UTF-8编码的最大长度是4个字节。从上表可以看出,4字节模板有21个x,即可以容纳21位二进制数字。Unicode的最大码位0x10FFFF也只有21位。
编码转换方式如:“汉”字的Unicode编码是0x6C49。0x6C49在0x0800-0xFFFF之间,使用3字节模板:1110xxxx 10xxxxxx 10xxxxxx。将0x6C49写成二进制是:0110 1100 0100 1001, 用这个比特流依次代替模板中的x,得到:11100110 10110001 10001001,即E6 B1 89。该示例中模板含有16个x,0x6C49转换为二进制刚好16位,因此不需要补0。若位数不足,则在前面补0。
2.2 UTF-16编码
U'可以被写成20个二进制位的原因是:Unicode的最大码位是0x10FFFF,减去0x10000后,U'的最大值是0xFFFFF,所以可以用20个二进制位表示。
编码转换方式如:Unicode编码0x20C30,减去0x10000后,得到0x10C30,写成二进制是:0001 0000 1100 0011 0000。用前10位依次替代模板中的y,用后10位依次替代模板中的x,就得到:1101100001000011 1101110000110000,即0xD843 0xDC30。
2.2.1 代理区
D800-DB7F
|
High Surrogates
|
高位替代
|
DB80-DBFF
|
High Private Use Surrogates
|
高位专用替代
|
DC00-DFFF
|
Low Surrogates
|
低位替代
|
高位替代就是指这个范围的码位是两个WORD的UTF-16编码的第一个WORD。低位替代就是指这个范围的码位是两个WORD的UTF-16编码的第二个WORD。
2.2.2 计算Unicode编码的范围
2.3 UTF-32编码
UTF-32编码以32位无符号整数为单位。Unicode的UTF-32编码就是其对应的32位无符号整数。
Unicode编码
|
UTF-16LE
|
UTF-16BE
|
UTF32-LE
|
UTF32-BE
|
0x006C49
|
49 6C
|
6C 49
|
49 6C 00 00
|
00 00 6C 49
|
0x020C30
|
30 DC 43 D8
|
D8 43 DC 30
|
30 0C 02 00
|
00 02 0C 30
|
根据UTF-16计算结果,根据大小端字节序显示。UTF32需要4个字节,不够就在前面补0。
相关常见的问题解答:http://www.unicode.org/faq/utf_bom.html