BOM(Byte Order Mark)及其他杂项
1、字节序标记是插入到以UTF-8、UTF-16或UTF-32编码Unicode文件开头的特殊标记,用于标识文本编码及字节序。
编码 | BOM |
UTF-8 | 0xEF 0xBB 0xBF |
UTF-16 BE | 0xFE 0xFF |
UTF-16 LE | 0xFF 0xFE |
UTF-32 BE | 0x00 0x00 0xFE 0xFF |
UTF-32 LE | 0xFF 0xFE 0x00 0x00 |
2、Unicode属于字符集,不属于编码,UTF-8、UTF-16等是针对Unicode字符集的编码。
UTF-8、UTF-16、UTF-32、UCS-2、UCS-4对比:
对比 | UTF-8 | UTF-16 | UTF-32 | UCS-2 | UCS-4 |
编码空间 | 0-10FFFF | 0-10FFFF | 0-10FFFF | 0-FFFF | 0-7FFFFFFF |
最少编码字节数 | 1 | 2 | 4 | 2 | 4 |
最多编码字节数 | 4 | 4 | 4 | 2 | 4 |
是否依赖字节序 | 否 | 是 | 是 | 是 | 是 |
3、字符文本由一个字符常量构成。 它由用单引号引起来的字符表示。 有四种类型的字符文本:
- 类型 char 的窄字符文本,例如 'a'
- 类型 wchar_t 的宽字符文本,例如 L'a'
- 类型 char16_t 的宽字符文本,例如 u'a'
- 类型 char32_t 的宽字符文本,例如 U'a'
4、常见汉字编码概述
GB2312编码:1981年5月1日发布的简体中文汉字编码国家标准。GB2312对汉字采用双字节编码,收录7445个图形字符,其中包括6763个汉字。
BIG5编码:台湾地区繁体中文标准字符集,采用双字节编码,共收录13053个中文字,1984年实施。
GBK编码:1995年12月发布的汉字编码国家标准,是对GB2312编码的扩充,对汉字采用双字节编码。GBK字符集共收录21003个汉字,包含国家标准GB13000-1中的全部中日韩汉字,和BIG5编码中的所有汉字。
GB18030编码:2000年3月17日发布的汉字编码国家标准,是对GBK编码的扩充,覆盖中文、日文、朝鲜语和中国少数民族文字,其中收录27484个汉字。GB18030字符集采用单字节、双字节和四字节三种方式对字符编码。兼容GBK和GB2312字符集。
Unicode编码:国际标准字符集,它将世界各种语言的每个字符定义一个唯一的编码,以满足跨语言、跨平台的文本信息转换。
汉字在Unicode中的分布
在Unicode中,中日韩的汉字集中在几个区域,但是它们之间是混在一起的。这几个区域分别是:
块名称 | 位置 | 汉字个数 | 描述 |
CJK Unified Ideographs | 4E00–9FFF | 20,991 | 常用字 |
CJK Unified Ideographs Extension A | 3400–4DBF | 6591 | 生僻字 |
CJK Unified Ideographs Extension B | 20000–2A6DF | 42,719 | 古汉字遗留的生僻字 |
CJK Unified Ideographs Extension C | 2A700–2B73F | 4,159 | 古汉字遗留的生僻字 |
CJK Unified Ideographs Extension D | 2B740–2B81F | 223 | 现在还在用,但使用较少 |
CJK Unified Ideographs Extension E | 2B820–2CEAF | 5,775 | 古汉字遗留的生僻字 |
CJK Compatibility Ideographs | F900–FAFF | 511 | 重复的变体字 |
CJK Compatibility Ideographs Supplement | 2F800–2FA1F | 543 | 变体字 |
总计 | 81,432 |
备注:查到的不同资料,汉字分布区间的字数不太一致,待确认。下面链接的分布表可作参考。
Unicode编码分布表: http://chineselanguageformula.sourceforge.net/traditional/unicode-planes.html
語種 | 分類 | 開始位置 | 結束位置 | 字數 |
統一漢字 | 中日韓越統一漢字 | U+004E00 | U+009FBF | 20928 |
統一漢字擴展集A | 中日韓越統一漢字 | U+003400 | U+004DBF | 6592 |
統一漢字擴展集B | 中日韓越統一漢字 | U+020000 | U+02A6DF | 42720 |
統一漢字擴展集C | 中日韓越統一漢字 | U+02A700 | U+02B734 | 4149 |
統一漢字擴展集D | 中日韓越統一漢字 | U+02B740 | U+02B81F | 224 |
統一漢字擴展集E | 中日韓越統一漢字 | U+02B820 | U+02F7FF | 16352 |
相容漢字 | 中日韓越統一漢字 | U+00F900 | U+00FAFF | 512 |
增補相容漢字 | 中日韓越統一漢字 | U+02F800 | U+02FA1F | 544 |
UTF-16描述
a fixed-width 2-byte encoding could not encode enough characters to be truly universal,于是UTF-16诞生了,与UCS-2一样,它使用两个字节为全世界最常用的63K字符编码,不同的是,它使用4个字节对不常用的字符进行编码。UTF-16属于变长编码。
UTF-16可看成是UCS-2的父集。在没有辅助平面字符(surrogate code points)前,UTF-16与UCS-2所指的是同一的意思。但当引入辅助平面字符后,就称为UTF-16了。现在若有软件声称自己支持UCS-2编码,那其实是暗指它不能支持在UTF-16中超过2字节的字集。对于小于0x10000的UCS码,UTF-16编码就等于UCS码。
Unicode的编码空间从U+0000到U+10FFFF,共有1,112,064个码位(code point)可用来映射字符。Unicode的编码空间可以划分为17个平面(plane),每个平面包含(65,536)个码位。17个 平面的码位可表示为从U+xx0000到U+xxFFFF,其中xx表示十六进制值从0016到1016,共计17个平面。
第一个平面称为基本多语言平面(Basic Multilingual Plane, BMP),或称第零平面(Plane 0)。其他平面称为辅助平面(Supplementary Planes)。基本多语言平面内,从U+D800到U+DFFF之间的码位区块是永久保留不映射到Unicode字符。UTF-16就利用保留下来的0xD800-0xDFFF区块的码位来对辅助平面的字符的码位进行编码。
从U+0000至U+D7FF以及从U+E000至U+FFFF的码位
第一个Unicode平面(码位从U+0000至U+FFFF)包含了最常用的字符。该平面被称为基本多语言平面,缩写为BMP(Basic Multilingual Plane, BMP)。UTF-16与UCS-2编码这个范围内的码位为16比特长的单个码元,数值等价于对应的码位. BMP中的这些码位是仅有的可以在UCS-2中表示的码位。
例:“汉”在Unicode中的码位为6C49,而在UTF-16编码也为6C49。
从U+10000到U+10FFFF的码位
辅助平面(Supplementary Planes)中的码位,在UTF-16中被编码为一对16比特长的码元(即32位,4字节),称作代理对(surrogate pair),具体方法是:
lead \ trail | DC00 | DC01 | … | DFFF |
D800 | 10000 | 10001 | … | 103FF |
D801 | 10400 | 10401 | … | 107FF |
⋮ | ⋮ | ⋮ | ⋱ | ⋮ |
DBFF | 10FC00 | 10FC01 | … | 10FFFF |
- 码位减去0x10000,得到的值的范围为20比特长的0..0xFFFFF.
- 高位的10比特的值(值的范围为0..0x3FF)被加上0xD800得到第一个码元或称作高位代理(high surrogate),值的范围是0xD800..0xDBFF.由于高位代理比低位代理的值要小,所以为了避免混淆使用,Unicode标准现在称高位代理为前导代理(lead surrogates)。
- 低位的10比特的值(值的范围也是0..0x3FF)被加上0xDC00得到第二个码元或称作低位代理(low surrogate),现在值的范围是0xDC00..0xDFFF.由于低位代理比高位代理的值要大,所以为了避免混淆使用,Unicode标准现在称低位代理为后尾代理(trail surrogates)。
例:"𪺫"的Unicode码位值为2AEAB,减去0x10000得到1AEAB,前10位加上D800得到D86B,后10位加上DC00得到DEAB。于是该字的UTF-16编码值为D86BDEAB(该值为大端表示,小端为6BD8ABDE)。
上述算法可理解为:辅助平面中的码位从U+10000到U+10FFFF,共计FFFFF个,即220=1,048,576个,需要20位来表示。如果用两个16位长的整数组成的序列来表示,第一个整数(称为前导代理)要容纳上述20位的前10位,第二个整数(称为后尾代理)容纳上述20位的后10位。还要能根据16位整数的值直接判明属于前导整数代理的值的范围(210=1024),还是后尾整数代理的值的范围(也是210=1024)。因此,需要在基本多语言平面中保留不对应于Unicode字符的2048个码位,就足以容纳前导代理与后尾代理所需要的编码空间。这对于基本多语言平面总计65536个码位来说,仅占3.125%.
由于前导代理、后尾代理、BMP中的有效字符的码位,三者互不重叠,搜索是简单的:一个字符编码的一部分不可能与另一个字符编码的不同部分相重叠。这意味着UTF-16是自同步(self-synchronizing):可以通过仅检查一个码元就可以判定给定字符的下一个字符的起始码元. UTF-8也有类似优点,但许多早期的编码模式就不是这样,必须从头开始分析文本才能确定不同字符的码元的边界。
从U+D800到U+DFFF的码位
Unicode标准规定U+D800..U+DFFF的值不对应于任何字符。
GB18030
GB18030有两个版本:GB18030-2000和GB18030-2005。
GB18030-2000是GBK的取代版本,它的主要特点是在GBK基础上增加了CJK统一汉字扩充A的汉字。
GB18030-2005的主要特点是在GB18030-2000基础上增加了CJK统一汉字扩充B的汉字。
---------------
GB18030-2000收录了27533个汉字:
类别 | 码位范围 | 码位数 | 字符数 | 字符类型 |
双字节部分 | 第一字节 0xB0-0xF7 第二字节 0xA1-0xFE | 6768 | 6763 | 汉字 |
第一字节0x81-0xA0 第二字节0x40-0xFE | 6080 | 6080 | 汉字 | |
第一字节0xAA-0xFE 第二字节0x40-0xA0 | 8160 | 8160 | 汉字 | |
四字节部分 | 第一字节0x81-0x82 第二字节0x30-0x39 第三字节0x81-0xFE 第四字节0x30-0x39 | 6530 | 6530 | CJK统一汉字扩充A |
27533就是6763+6080+8160+6530。双字节部分的6763+6080+8160=21003个汉字就是GBK的21003个汉字。
在Unicode中,CJK统一汉字扩充A有6582个汉字,为什么这里只有6530个汉字?
这是因为在GBK时代,双字节部分已经收录过CJK统一汉字扩充A的52个汉字,所以还余6530个汉字。
-----------------
GB18030-2005收录了70244个汉字:
类别 | 码位范围 | 码位数 | 字符数 | 字符类型 |
双字节部分 | 第一字节 0xB0-0xF7 第二字节 0xA1-0xFE | 6768 | 6763 | 汉字 |
第一字节0x81-0xA0 第二字节0x40-0xFE | 6080 | 6080 | 汉字 | |
第一字节0xAA-0xFE 第二字节0x40-0xA0 | 8160 | 8160 | 汉字 | |
四字节部分 | 第一字节0x81-0x82 第二字节0x30-0x39 第三字节0x81-0xFE 第四字节0x30-0x39 | 6530 | 6530 | CJK统一汉字扩充A |
第一字节0x95-0x98 第二字节0x30-0x39 第三字节0x81-0xFE 第四字节0x30-0x39 | 42711 | 42711 | CJK统一汉字扩充B |
70244就是6763+6080+8160+6530+42711。
-----------------
GB2312有6763个汉字,GBK有21003个汉字,GB18030-2000有27533个汉字,GB18030-2005有70244个汉字。
Unicode 5.0中,如果不算兼容区,目前有70217个汉字。让我们比较一下Unicode的70217汉字和GB18030-2005中的70244汉字:
GB18030-2005 | Unicode 5.0 | 对应的Unicode编码 |
CJK统一汉字的20902汉字 | CJK统一汉字的20902汉字 | 0x4E00-0x9FA5 |
CJK统一汉字扩充A的6582汉字 | CJK统一汉字扩充A的6582汉字 | 0x3400-0x4DB5 |
CJK统一汉字扩充B的42711汉字 | CJK统一汉字扩充B的42711汉字 | 0x20000-0x2A6D6 |
CJK部首补充区的14个部首 | 未计入 | 2E81, 2E84, 2E88, 2E8B, 2E8C, 2E97, 2EA7, 2EAA, 2EAE, 2EB3, 2EB6, 2EB7, 2EBB, 2ECA |
CJK兼容汉字区的21个汉字 | 未计入 | F92C, F979, F995, F9E7, F9F1, FA0C, FA0D, FA0E, FA0F, FA11, FA13, FA14, FA18, FA1F, FA20, FA21, FA23, FA24, FA27, FA28, FA29 |
8个部首 | CJK统一汉字区新增了这8个字符 | 0x9FB4-0x9FBB |
未计入 | CJK统一汉字区新增的14个字符 | 0x9FA6-0x9FB3 |
8个部首:
CJK统一汉字区新增的0x9FA6-0x9FB3这14个字符在GB18030中有对应的码位(0x82358F33-0x82358F39, 0x82359030-0x82359039, 0x82359130-0x82359134),不过GB18030没有列出这些字符。
重要资料:
谈谈Unicode编码,简要解释UCS、UTF、BMP、BOM等名词
Unicode、GB2312、GBK和GB18030中的汉字
GB18030编码研究以及GBK、GB18030与Unicode的映射
细说:Unicode, UTF-8, UTF-16, UTF-32, UCS-2, UCS-4