字符编码发展史5 — UTF-16和UTF-32

上一篇《字符编码发展史4 — Unicode与UTF-8》我们讲解了Unicode字符集与UTF-8编码。本篇我们将继续讲解字符编码的第三个发展阶段中的UTF-16和UTF-32。

2.3. 第三个阶段 国际化

2.3.2. Unicode的编码方式

2.3.2.2. UTF-16

UTF-16也是一种变长编码,对于一个Unicode字符被编码成1至2个码元,每个码元为2个字节(16位)。UTF-16编码会有字节序的问题,所以根据大小端又分为大端UTF-16(UTF-16 BE)和小端UTF-16(UTF-16 LE)。

1. 基本平面(码点范围U+0000-U+FFFF)

在基本多语言平面内的码位UTF-16编码使用1个码元且其值与Unicode是相等的(不需要转换)。举例如下:

Unicode 字符 UTF-16(码元) UTF-16 LE(字节) UTF-16 BE(字节)
U+0041 A 0x0041 0x41 0x00 0x00 0x41
U+03A9 Ω 0x03A9 0xA9 0x03 0x03 0xA9
U+6653 0x6653 0x53 0x66 0x66 0x53
2. 辅助平面(码点范围U+10000-U+10FFFF)

辅助平面的码点在UTF-16中被编码为一对双字节(16位)的码元(即32位,4字节),称作代理对(surrogate pair),编号范围:0xD800~0xDFFF,也就是前文提到的代理区的范围。这也就是为什么基本多语言平面会保留一块代理区(0xD800~0xDFFF)的码点不定义任何字符的原因。

组成代理对的两个码元前一个称为前导代理(lead surrogates)范围为0xD800-0xDBFF,可表达1024(2^10)个码元;后一个称为后尾代理(trail surrogates)范围为0xDC00-0xDFFF,可表达1024(2^10)个码元。这样两个码元组合在一起就可以表达 2^20(2^10 * 2 ^ 10)个编码,正好和辅助平面的码点范围U+10000-U+10FFFF对应。

UTF-16辅助平面代理对与Unicode的对应关系如下表。

  • 第一列: 表示前导代理。
  • 第一行: 表示后尾代理。
  • 表格内容: 表示Unicode的码点编号。
\ 0xDC00 0xDC01 0xDFFF
0xD800 U+10000 U+10001 U+103FF
0xD801 U+10400 U+10401 U+107FF
0xDBFF U+10FC00 U+10FC01 U+10FFFF

举例如下

Unicode 字符 UTF-16(码元) UTF-16 LE(字节) UTF-16 BE(字节)
U+2A6A5 𪚥 0xD869 0xDEA5 0x69 0xD8 0xA5 0xDE 0xD8 0x69 0xDE 0xA5
3. 优缺点
  • 优点:
    1. 绝大部分的文字都可以用两个字节编码,对于CJK文字是比较节省空间的;
    2. 文本处理比UTF-8方便得多。
  • 缺点:
    1. 存储和传输需要考虑字节序的问题;
    2. 不兼容ASCII(准确的说是半兼容,编码值是一样的,只是需要用两个字节来表示)。

2.3.2.3. UTF-32

1. UTF-32的编码规则

UTF-32是一种定长编码,使用1个32bit的码元,其值与Unicode编码值相等。举例如下:

Unicode 字符 UTF-32(码元) UTF-32 LE(字节) UTF-32 BE(字节)
U+0041 A 0x00000041 0x41 0x00 0x00 0x00 0x00 0x00 0x00 0x41
U+03A9 Ω 0x000003A9 0xA9 0x03 0x00 0x00 0x00 0x00 0x03 0xA9
U+6653 0x00006653 0x53 0x66 0x00 0x00 0x00 0x00 0x66 0x53
U+2A6A5 𪚥 0x0002A6A5 0xA5 0xA6 0x02 0x00 0x00 0x02 0xA6 0xA5

UTF-32同样有大小端的问题。

2. 优缺点
  • 优点:是编码定长容易进行文本处理。
  • 缺点:是浪费存储空间及存在字节序的问题。

2.3.2.4. UCS-2 与 UCS-4

前文提到:历史上存在两个独立的尝试创立单一字符集的组织,即 国际标准化组织(ISO)和统一码联盟。统一码联盟除了收录字符集外,还制定过两套字符编码方案:UCS2和UCS4。

1. UCS-2

UCS-2是一种定长编码,编码范围为0x0000-0xFFFF,在基本多语言平面内与UTF-16是等价。UCS2没有类似于UTF-16中代理对的概念,所以对于0xD869 0xDEA5会识别成两个字符。所以它只能表示基本平面的字符,不能表示全部的Unicode字符。UCS2后来被UTF-16替代,现在基本已经被废弃了。

2. UCS-4

UCS-4的编码方式与UTF-32几乎一样,后来两个组织统一标准后,就变成了UTF-32。不过ISO组织规定Unicode的编码空间会限定在0x000000~0x10FFFF之间,而UCS4的编码范围能到0~0xFFFFFFFF。因此也可以认为:UTF-32 是 UCS-4 的一个子集。


未完待续…… 欲知后事如何,且看下回分解。

下回预告:字符编码发展史6 — BOM字节序标记。

历史文章推荐:

字符编码发展史4 — Unicode与UTF-8

字符编码发展史3 — GB2312/Big5/GBK/GB18030

字符编码发展史2 — ISO-8859-N

字符编码发展史1 — ASCII和EASCII


大家好,我是陌尘。

IT从业10年+, 北漂过也深漂过,目前暂定居于杭州,未来不知还会飘向何方。

搞了8年C++,也干过2年前端;用Python写过书,也玩过一点PHP,未来还会折腾更多东西,不死不休。

感谢大家的关注,期待与你一起成长。



【SunLogging】
扫码二维码,关注微信公众号,阅读更多精彩内容