字符编码笔记
ASCII 编码简介
ASCII 编码称为美国信息交换标准代码,使用一个字节来编码,最高位始终为0,所以总共可以表示128个字符,目前分配情况如下:
- 0x00-0x1F,控制字符(不可见);
- 0x20,空格字符(可见);
- 0x21-0x7E,包括符号、字母和数字(可见);
- 0x7F,删除字符(不可见)。
ISO8859 编码简介
ASCII 编码最高位始终是0,只使用低七位进行编码,总共编码128个字符,如果将最高位用上,可以再编码128个字符。ASCII 编码是美国标准,所以欧洲有些符号并未包含其中,于是利用字节的最高位对 ASCII 编码进行扩展便产生了 ISO8859 编码。
ISO8859 编码并不是一个标准,其包含16个编码标准,每个标准中0x00-0x7F(即最高位是0)区段表示的字符与 ASCII 编码相同,0x80-0xFF(即最高位是1)区段表示的字符根据标准而异,其定义如下:
- 当最高位为0时,0x00-0x7F,保持与 ASCII 编码兼容;
- 当最高位为1时,0x80-0x9F,保留给扩充定义的32个控制码;
- 当最高位为1时,0xA0,在各个 ISO8859 编码中都表示非换行空格;
- 当最高位为1时,0xA1-0xFF,扩充的字符,根据标准而异。
Unicode 简介
Unicode 也称为万国码,主要为了解决传统字符编码方案的局限性,它为每种语言中的每个字符分配统一并且唯一的编码,即定义一个整数来表示某字符。以解决跨平台信息交换的问题。Unicode 并不定义字形,字符的展示工作留给其它软件来处理。目前最新版本为第六版,已经收录了超过十万个字符,至今还在不断增加,具体内容可参考 Unicode Roadmaps。
Unicode 包含17个平面,平面可以理解为编码区段,每个平面有65536(即2^16)个代码点,即可以编码65536个字符,目前用到的只有少数平面。第0平面叫基本多文种平面,其它16个平面称为辅助平面。一个 Unicode 字符至少要用21位来编码,略少于3字节。目前用到的平面如下:
- BMP,第 0平面,U+0000 0000-U+0000 FFFF,基本多文种平面;
- SMP,第 1平面,U+0001 0000-U+0001 FFFF,多文种补充平面;
- SIP,第 2平面,U+0002 0000-U+0002 FFFF,表意文字补充平面;
- TIP,第 3平面,U+0003 0000-U+0003 FFFF,表意文字第三平面;
- SSP,第14平面,U+000E 0000-U+000E FFFF,特别用途补充平面。
最常用到的是基本多文种平面,占用两个字节,基本多文种平面的分区如下:

Unicode 转换格式
Unicode 编码系统分为编码方式和实现方式两个层次。编码方式规定某字符的编码是什么,即代表此字符的整数值是什么;实现方式规定此整数值应该如何存储。编码方式已经通过17个平面来解决,下面讨论实现方式。
可以将 Unicode 编码值直接用于存储么?由于基本多文种平面字符的平面序号是0,所以两个字节即可表示这些字符,而辅助平面字符要用三个字节来表示。如果一个文件包含100个'N'和100个'七','N'的 Unicode 编码是0x004E,'七'的 Unicode 编码是0x4E04。要将这200个字符存储到文件中,字符的表示方式可以采用固定字节数,即不管是 ASCII 字符还是汉字字符都用相同的字节数来表示;也可以采用变长字节数,即有些高字节是0的字符可以将其省掉,从而减少该字符所占用的字节数。
如果采用第一种方式存储,比如用4个字节来表示一个字符,那么存储'N'的时候计算机会将0x0000004E写入文件,本来只需要1个字节即可表示,现在浪费掉3个字节,而一个'七'也会浪费2个字节。这个文件占用的空间将达到800个字节,浪费掉500个字节。
如果采用第二种方式存储,那么存储'N'的时候计算机会将0x4E写入文件,存储'七'的时候计算机会将0x4E04写入文件,不会存在任何的空间浪费。不过,当计算机读文件的时候遇到4E这个字节,它应该将其认为是字母'N',还是将其认为是汉字'七'的高位呢?
表示一个字符的时候,固定字节数可能会引起巨大的浪费,显然是不可取的,只能使用变长字节数,但 Unicode 编码值不能直接用来存储,所以必须将 Unicode 编码转换成另外一种编码。UTF(Unicode 转换格式)就是为了解决此问题而诞生的,主要包括 UTF-8、UTF-16、UTF-32,最常用到的是 UTF-8 编码,它使用一至六个字节来为某个字符编码,当计算机读到文件中某个字节的时候,其判定规则如下:
- 当第一个0位之前的1的个数等于0时,即此字节最高位是0,那么此字节代表 ASCII 字符;
- 当第一个0位之前的1的个数大于1时,那么此字节代表多字节字符的开始,且1的个数表示此多字节字符的字节数;
- 当第一个0位之前的1的个数等于1时,那么此字节代表多字节字符的后部。
Unicode 编码的范围是0x00000000-0x0010FFFF,Unicode 编码转换为 UTF-8 编码的详细规则如下:
Unicode | UTF-8
(hexadecimal) | (binary)
--------------------+------------------------------------
0000 0000-0000 007F | 0xxxxxxx
0000 0080-0000 07FF | 110xxxxx 10xxxxxx
0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
浙公网安备 33010602011771号