在前面一篇博文中介绍了UTF-8编码实现,并简单介绍了Unicode编码。它们之间的关系就是字符的抽象与实现的关系。在抽象的字符集中,每个字符通过唯一的code point码位(一个整数,一般用十六进制)表示。但是在实际的存储、传输过程中需要“编码的实现”,UTF-8就是其中一种。还有其他的实现方式如UCS-2、UTF-16等。
Unicode的码空间从U+0000到U+10FFFF,共有1,112,064个码位(code point)可用来映射字符. Unicode的码空间可以划分为17个平面(plane),每个平面包含216(65,536)个码位。每个平面的码位可表示为从U+xx0000到U+xxFFFF, 其中xx表示十六进制值从0016 到1016,共计17个平面。
第一个Unicode平面(码位从U+0000至U+FFFF)包含了最常用的字符,该平面被称为基本多语言平面(Basic Multilingual Plane),缩写为BMP。其他平面称为辅助平面(Supplementary Planes)。
下图是BMP的示意图,其中每个小块表示256个字符,所以上面的两个十六进制表示Unicode的高8位。例如汉字的码位大概处在0x3400~0x4DBF(中日韩统一表意文字扩展A区)和0x4e00~0x9FFF(中日韩统一表意文字)。在图中就是大概34-9F中间,除去一点粉红色区域(64个码位)。汉字编码还有扩展B区、C区等,它们不在0平面内。
这个是0x4e00~0x9FFF对应的汉字码表。
关于1,114,112和1,112,064这两个数字之间的差为2048。首先得明白这个三个数是怎么来的。
Unicode码空间为U+0000到U+10FFFF,一共有17个平面,每个平面可容下65536个code point。也就是17*65536=1,114,112。但是其中的U+D800-U+DF00作为UTF-16编码代理区保留,也就是它们不会作为code point分配给字符,保留数目是8*256=2048。关于UTF-16与UCS-2之间的关系另外再详述。
字符在机器内部的表示(内码)
现在主流的操作系统的字符内码一般都用UTF-16来表示字符。所以通过其他编码格式的字符在交由计算机处理之前必须被解码成机器内码,才可以被正确处理。不同编码格式之间的转化也必须经由内码才比较不容易出错。