总结一下常用的中文编码。

Unicode 编码

Unicode 是基于国际标准化组织(International Organization for Standardization,简称 ISO)所制定的 ISO/IEC 10646 ,即通用字符集(Universal Character Set,简称 UCS)的标准来发展,在 1991 年首次以书本的形式(The Unicode Standard)对外发布。

Unicode 的编码方式与 ISO 10646 的通用字符集(UCS)概念相对应,使用 16 位编码空间。16 位 Unicode 字符构成基本多文种平面(Basic Multilingual Plane,简称 BMP),最多可以表示 65536 个字符。基本满足各种语言的使用。最新的 Unicode 版本定义了 16 个辅助平面,两者合起来达到 32 位编码空间,可以涵盖一切语言所用的符号。目前辅助平面的工作主要集中在第二和第三平面的中日韩统一表意文字中。

Unicode 只与 ASCI I 兼容(更准确地说,是与 ISO-8859-1 兼容),与 GB 码不兼容。例如“汉”字的 Unicode 编 码是 6C49,而 GB 码是 BABA。

以上都是废话,下面重点:

  • 设计目的是为了表达任意语言的任意字符
  • 使用 4 字节来表示,被几种语言共用的字符通常使用相同的数字来编码
  • 每个编码数字对应一个字符

理想是好的,一种编码解决所有问题。但是问题随即出现,对于英语这样的语言,1 个字节都不需要即可表达所有字符,而每个字符都需要 4 个字节的 Unicode 编码有些浪费空间。

UTF-16 编码

尽管有 Unicode 字符非常多,但是实际上大多数人不会用到超过前 65535 个以外的字符。因此有了 UTF-16 (2 字节)编码,UTF-16 编码最明显的优点就是空间效率要比 Unicode 编码高两倍(除去 65535 意外的字符,每个字符只需要 2 个字节)

UTF 的字节序和 BOM

UTF-8 以字节为编码单元,没有字节序的问题。UTF-16 以两个字节为编码单元,在解释一个 UTF-16 文本前,首先要弄清楚每个编码单元的字节序。例如“奎”的 Unicode 编码是 U+594E, “乙”的 Unicode 编码是 U+4E59。如果我们收到 UTF-16 字节流“594E”,那么这是“奎” 还 是“乙”?

Unicode 规范中推荐的标记字节顺序的方法是 BOM。BOM 不是“Bill Of Material”的 BOM 表,而是 Byte Order Mark,他是一个特殊的非打印字符,可以把它包含在文档的开头用来指示所使用的字节顺序。对于 UTF-16 字节顺序的标记为 U+FEFE。

在 UCS 编码中有一个叫做”ZERO WIDTH NO-BREAK SPACE”的字符,它的编码是 FEFF。而 FFFE 在 UCS 中是不存在的字符,所以不应该出现在实际传输中。UCS 规范建议我们在传输字节流 前,先传输字符”ZERO WIDTH NO-BREAK SPACE”。

这样如果接收者收到 FEFF,就表明这个字节流是 Big-Endian 的;如果收到 FFFE,就表明这 个字节流是 Little-Endian 的。因此字符”ZERO WIDTH NO-BREAK SPACE”又被称作 BOM。UTF-8 不需要 BOM 来表明字节顺序,但可以用 BOM 来表明编码方式。字符”ZERO WIDTH NO-BR EAK SPACE”的 UTF-8 编码是 EF BB BF。

UTF-8

UTF-16 不够完美,不是所有字符都能够使用 2 个字节长来表达,所以要在常数时间内定位到第 N 个字符,就不得不维护另外的索引,也就影响了编码本身的设计目的。所以就有了 UTF-8 编码,它是一种可变长度编码,可以用来表示 Unicode 标准中的任意字符。UTF-8 是一种前缀码,什么是前缀码:

  • 对于 UTF-8 编码中的任意字节 B,如果 B 的第一位为 0,则 B 独立的表示一个字符 (ASCII 码);
  • 如果 B 的第一位为 1,第二位为 0,则 B 为一个多字节字符中的一个字节(非 ASCII 字符);
  • 如果 B 的前两位为 1,第三位为 0,则 B 为两个字节表示的字符中的第一个字节;
  • 如果 B 的前三位为 1,第四位为 0,则 B 为三个字节表示的字符中的第一个字节;
  • 如果 B 的前四位为 1,第五位为 0,则 B 为四个字节表示的字符中的第一个字节;

因此,对 UTF-8 编码中的任意字节,根据第一位,可判断是否为 ASCII 字符;根据前二位,可判断该字节是否为一个字符编码的第一个字节;根据前四位(如果前两位均为 1),可确定该字节为字符编码的第一个字节,并且可判断对应的字符由几个字节表示;根据前五位(如果前四位为 1),可判断编码是否有错误或数据传输过程中是否有错误。

编码对应 Unicode 和 UTF-8 转换关系

位数 字节序列 byte 1 byte 2 byte 3 byte 4 byte 5 byte 6
7 U+0000 U+007F 1 0xxxxxxx          
11 U+0080 U+07FF 2 110xxxxx 10xxxxxx        
16 U+0800 U+FFFF 3 1110xxxx 10xxxxxx 10xxxxxx      
21 U+10000 U+1FFFFF 4 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx    
26 U+200000 U+3FFFFFF 5 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx  
31 U+4000000 U+7FFFFFFF 6 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx  

GB2312 编码

GB 2312-80 编码是中华人民共和国国家标准汉字信息交换用编码,全称《信息交换用汉字编码字符集基本集》标准号为 GB 2312-80(GB 是“国标”二字的汉语拼音缩写),由中华人民共和国国家标准总局发布,1981 年 5 与 1 号发布,1981 年 10 月 1 日实施。它是一个简化字汉字的编码,通行于中国大陆地区及海外使用简体中文的地区(如新加坡等)。

GB 2312-80 收录简化汉字及一般符号、序号、数字、拉丁字母、日文假名、希腊字母、俄文字母、汉语拼音符号、汉语注音字母、共 7445 个图形字符。其中汉字以外的图形字符 682 个,汉字 6763 个。

GB 2312-80 把收录的汉字分成两级。第一级汉字是常用汉字,计 3755 个,置于 16~55 区,按汉语拼音字母 / 笔形顺序排列;第二级汉字是次常用汉字,计 3008 个,置于 56~87 区,按部首 / 笔画顺序排列。字音以普通话审音委员会发表的《普通话异读词三次审音总表初稿》(1963 年出版)为准,字形以中华人民共和国文化部、中国文字改革委员会公布的《印刷通用汉字字形标》(1964 年出版)为准。

GBK 编码

GBK 编码标准,全称《汉字内码扩展规范》(GBK),英文名称 Chinese Internal Code Specification,中华人民共和国全国信息技术标准化技术委员会 1995 年 12 月 1 日制定,国家技术监督局标准化司、电子工业部科技与质量监督司 1995 年 12 月 15 日联合以技监标函 [1995]229 号文件的形式,将它确定为技术规范指导性文件,发布和实施。这一版的 GBK 规范为 1.0 版。GB 即“国标”,K 是“扩展”的汉语拼音第一个字母。

GBK 向下与 GB 2312 编码兼容,向上支持 ISO 10646.1 国际标准,是前者向后者过度过程中的一个承上启下的标准。GBK 共收录 21886 个汉字和图形符号,其中汉字(包括部首和构件)21003 个,图形符号 883 个。

GB2312 的 code page 是 CP20936,GBK 的 code page 是 CP936。GB18030 支持的字符数更多。GB2312、GBK、GB18030 均为双字节。从 ASCII、GB2312、GBK 到 GB18030 的编码方法是向下兼容的。

举一个最简单的例子,比如 字,在 GB 2312 解码时可能就是乱码,而 CP936 并不会。

GB 18030 编码

GB 18030 有两个版本:GB 18030-2000 和 GB 18030-2005. GB 18030-2000 是 GBK 的取代版本,它的主要特点是在 GBK 的基础上增加了 CJK 统一汉字扩充 A 的汉字,GB 18030-2005 的主要特点是在 GB 18030-2000 基础上增加了 CJK 统一汉字扩充 B 的汉字。

GB 18030-2000,全称《信息技术 信息交换用汉字编码字符集 基本集的扩充》,中华人民共和国信息产业部电子工业标准化研究所起草,由国家质量技术监督局于 2000 年 3 月 17 号发布。GB 18030-2000 共收录 27533 个汉字。

GB 18030,全称:国家标准 GB 18030-2005《信息技术 中文编码字符集》,是中华人民共和国现在最新的内码字符集,是 GB 18030-2000 的修订版。GB18030-2005 共收录汉字 70244 个。现行版本为国家质量监督检验总局和中国国家标准化管理委员会于 2005 年 11 月 8 日发布,2006 年 5 月 1 日实施。此规格为在中国境内所有软件产品支持的强制规格。

BIG 5 字符集

BIG-5 码是通行于台湾、香港地区的一个繁体字编码方案,俗称“大五码”。

BIG-5 码收录 13468 个符号和汉字,符号 408 个,汉字 13060 个,分为常用字和次常用字两部分,各部分中的汉字按照笔画 / 部首排列。其中:常用字 5401 个,次常用字 7659。

GB/T 12345 编码

GB/T 12345-90 编码全称《信息交换用汉字编码字符集 辅助集》,标准号为 GB/T 12345-90,1990 年 6 月 13 日发布,1990 年 12 月 1 日实施,是一个关于繁体字的编码标准。所谓“辅助集”,是与“基本集”(GB2312-80)相对应而言。即:GB/T 12345 是与 GB2312 相对应的图形字符集。原则上,本字符集是将 GB2312 中的简化字用相应的繁体字替换而成。因此,这些替代的繁体字具有与被替代的简化字相同的编码;未曾简化的汉字以及非汉字图形字符,仍是 GB2312 中的汉字和图形字符,并具有与之相同的编码。 GB/T 12345-90 共收录 7583 个图形字符。汉字以外的图形字符 716 个,汉字 6866 个,其中一级汉字 3755 个,二级汉字 3008 个,增补汉字 103 个。 关于繁体字替换简化字的原则,GB/T 12345 注明:“本标准原则上按照《简化字总表》中所列繁体字与简化字的对应关系进行替换。”《简化字总表》由中国文字改革委员会 1964 年 5 月发表,后经国家语言文字工作委员会作个别修改,国务院 1986 年 6 月 4 号批准发表。

748 编码

748 编码仅用于方正软件和系统,不做介绍