录十六

持之以恒

字符编码之Unicode简介

上个世纪60年代,美国制定了一套字符编码,对英语字符与二进制位之间的关系,做了统一规定。这被称为 ASCII 码,一直沿用至今。随着计算机发展到世界各地,各个国家和地区为了实现计算机系统中语言的本地化,搞出了很多既兼容ASCII但又互相不兼容的编码方案。这样一来同一个二进制编码就有可能被解释成不同的字符,导致不同的字符集在交换数据时,带来极大的不便。

一、Unicode历史简介

如果有一种统一的编码方案,将世界上所有语言字符都纳入其中,每一个字符都给予一个全球独一无二的编码,那么乱码问题就会消失。于是,全球所有国家和民族使用的所有语言字符的统一编码方案诞生了。

最初,由多语言软件制造商组成了统一码联盟(The Unicode Consortium),并于1991年发布了统一码标准(The Unicode Standard),定义了一个全球统一的通用字符集,习惯简称为Unicode字符集。

接着,ISO及IEC也于1993年联合发布了称之为通用多八位编码字符集(Universal Multiple-Octet Coded Character Set)、简称为UCS(Universal Character Set),标准号为ISO/IEC 10646-1的全球统一的通用字符集。

后来,统一码联盟与ISO/IEC双方都意识到世界上没有必要存在两套全球统一的通用字符集,于是进行整合,并为创立一个单一的全球统一的通用字符集而协同工作。到Unicode 2.0时,Unicode字符集和UCS字符集(ISO/IEC 10646-1)基本保持了一致。

虽然,现在两个项目仍都存在,并独立地公布各自的标准,但统一码联盟和ISO/IEC都同意保持两者的通用字符集相互兼容,并共同调整未来的任何扩展。不过由于Unicode这一名字比较好记,因而它使用更为广泛。

二、Unicode编码方案概述

Unicode是为整合全世界的所有语言文字而诞生的。任何文字在Unicode中都对应一个值,这个值称为代码点(code point)。Unicode字符集将所有字符按照使用频率划分为17个平面,每个平面上的编号空间有2^16=65536个代码点。其中第0个平面BMP(Basic Multilingual Plane)、被称为基本多语言平面,它基本涵盖了当今世界上正在使用中的常用字符。我们平常用到的Unicode字符,一般都是位于BMP平面上的。

BMP平面以外其它的增补平面,又称为辅助平面。要么用来表示一些非常特殊的字符,比如不常用的象形文字、远古时期的文字等,且多半只有专家在历史和科学领域里才会用到它们;要么被留作扩展之用。

另外,BMP平面有一个专用区(Private Use Zone):0xE000~0xF8FF,共6400个代码点,被保留为专用。因而它永远不会被分配给任何字符;还有一个被称为代理区(Surrogate Zone)的特殊区域:0xD800-0xDFFF(十进制55296~57343),共2048个码点。目的是用基本平面BMP中的两个码点“代理”,表示BMP以外的其它增补平面的字符。

三、UCS字符集

国际标准ISO/IEC定义的通用字符集UCS,它分为UCS-2(2-byte Universal Character Set)和UCS-4(4-byte Universal Character Set)两部分,分别以2字节和4字节表示字符编号。

其中,UCS-2又被称为基本多语言平面BMP(Basic Multilingual Plane),与Unicode的基本多语言平面BMP保持了一致;而UCS-4格式用四个字节中的31位来表示一个字符的编号,这样可表示21亿个不同的字符(2^31=2147483648),最高位为0,另有用途。

实践中UCS字符集应用得不多,基本以Unicode字符集为主,因此不作详细介绍。

四、UTF-8与UTF-16编码

Unicode编码只规定了代码点和文字之间的对应关系,并没有规定代码点在计算机中如何存储。规定存储方式的称为UTF(Unicode Transformation Format)。其中,最常见应用较多的就是UTF-16和UTF-8。。

1. UTF-16

UTF-16采用的是变长编码方式,每个字符使用一个或两个无符号16位整数表示。另外,  大于0x10FFFF的字符不能使用UTF-16进行编码。

UTF-16具体的编码规则如下:

(1)当字符的代码点U∈(0x00000,0x10000]时,用一个16位的整数表示即可,它的编码值与代码点U相等。

(2)当字符的代码点U∈[0x10000,0x10FFFF]时, U' = U - 0x10000,那么U' ≤ 0xFFFFF,则U'可以用20个bit位表示。初始化两个16位整数W1 = 0xD800和W2 = 0xDC00,W1 和W2的低10个bit位是空闲的。那么可以将U'的高10个bit位分配给W1, 低10个bit位分配给W2

(3)当字符的代码点U>0x10FFFF时,不能进行UTF-16编码。

注意,Windows平台下默认的Unicode编码为小端(Little Endian)模式的UTF-16

2. UTF-32

3. UTF-8

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

Copyright © 1999-2019, lu16.com, All Rights Reserved