Skip to content
字数
1239 字
阅读时间
5 分钟

好的,这是一个非常核心且有趣的问题!Unicode之所以有17个平面,其原因根植于它的历史演变和一项巧妙的技术设计,这个设计主要是为了解决一个重大的向后兼容性问题。

简单来说,答案是:最初的设计只打算用1个平面,但后来发现不够用。为了在不破坏现有系统的情况下进行扩展,引入了一种名为“代理对” (Surrogate Pairs) 的机制,这种机制刚好能额外映射出16个平面,所以 1 + 16 = 17个平面。

下面我们来详细拆解这个过程:

1. 最初的设想:一个16位的世界 (1个平面)

  • 在Unicode标准诞生之初,设计者们认为一个16位的编码空间就足够了。
  • 计算一下:16位 (bit) 可以表示 2¹⁶ = 65,536 个不同的值。
  • 这个包含65,536个码位的空间,就是我们今天所说的基本多文种平面 (Basic Multilingual Plane, BMP),也就是0号平面
  • 在当时,这似乎足以容纳世界上所有最常用的现代文字,包括拉丁字母、汉字、日文假名、韩文等等。当时最流行的编码方式UCS-2就是基于这个设想,它将每个字符都用一个16位的单元来表示。

2. 现实的挑战:65,536个位置不够用了!

随着时间的推移,Unicode联盟意识到最初的设想太乐观了。有几个因素导致了空间的不足:

  • 历史文字:需要收录大量的古代文字和已经不再使用的书写系统。
  • 生僻汉字:东亚地区有大量的生僻字和方言字需要编码。
  • 专业符号:数学、音乐、炼金术等领域有海量的专业符号。
  • 表情符号 (Emoji):这是后来出现的一个巨大的需求。

很明显,一个平面(BMP)已经无法满足需求。

3. 关键的抉择:如何扩展?

此时Unicode面临一个巨大的难题:如何扩展码位空间,同时又不让那些已经按照“一个字符=16位”来设计的软件和系统(比如Windows NT、Java等)完全崩溃?

如果直接宣布“我们现在改用32位编码”,那么所有现存的软件都需要重写,这将是一场灾难。

4. 巧妙的解决方案:UTF-16 和代理对 (Surrogate Pairs)

为了解决这个问题,UTF-16编码诞生了。它通过一个叫做**“代理对”**的机制,巧妙地扩展了Unicode的寻址空间。

具体做法如下:

  1. 保留一段空间:在0号平面(BMP)中,他们永久性地保留了一段范围的码位:从 U+D800U+DFFF。这段范围内的码位不代表任何有效字符,它们被专门用作“代理”。

  2. 一分为二:这段保留的范围被分成两部分:

    • 高代理区 (High Surrogates)U+D800U+DBFF (共1024个码位)。
    • 低代理区 (Low Surrogates)U+DC00U+DFFF (共1024个码位)。
  3. 配对使用:当系统遇到一个高代理区的码位时,它就知道这只是半个字符,后面必须紧跟着一个低代理区的码位。这两个16位的码位组合在一起,通过一个特定的数学公式,就可以映射到一个超出0号平面的新码位。

  4. 计算一下能表示多少新字符

    • 高代理有1024种可能。
    • 低代理有1024种可能。
    • 总的组合数 = 1024 × 1024 = 1,048,576 个。

    所以,代理对机制额外创造了1,048,576个码位空间。

5. 连接到“17个平面”

现在,我们把所有部分组合起来:

  • 每个Unicode平面包含 65,536 (即 2¹⁶) 个码位。

  • 代理对机制额外创造了 1,048,576 个码位。

  • 那么这些额外的码位可以组成多少个新平面呢?

    • 1,048,576 ÷ 65,536 = 16
  • 最终结果

    • 原有的 1 个基本平面 (BMP, Plane 0)
    • 通过代理对机制扩展出的 16 个辅助平面 (Supplementary Planes, Plane 1 到 Plane 16)
    • 总计:1 + 16 = 17个平面

因此,Unicode拥有17个平面,这个数字是其从16位编码向更大空间扩展时,为了保持向后兼容性而采用的UTF-16代理对技术所直接导致的结果。

贡献者

页面历史