不是用来写字的码点:边界、保留、私用与回退记号
一面国旗在某些设备上只显示成两个字母方块,一个 U+10FFFF 是整个 Unicode 的最后一个码点——它们提醒我们:code point 不等于普通可见字符。码空间
U+0000 ~ U+10FFFF 里,有的码点是边界、有的永久保留给机制(代理区)、有的标准永不定义(私用区与非字符)、有的是控制或回退记号(替换符 �、bidi 反转、单用的 Regional Indicator)。
1 · 码点探针
输入或拖一个 code point(0 到 0x10FFFF),实时报它落在哪个区、是不是合法 scalar value、属不属于代理 / 非字符 / 私用,以及本浏览器的属性类怎么判它。
注 · scalar value 与 code point 不是一回事。代理区 U+D800 ~ U+DFFF 这 2048 个号是 code point,但不是 Unicode scalar value——它们专门留给 UTF-16 代理对 拼补充平面字符,单独出现不能合法编码。能正常出现在文本里的,是 scalar
value,即全体码点减去代理区。
2 · 码空间地图
Unicode 码空间分成 17 个平面,每个平面 65536 个码点,共 1 114 112 个——尽头正是 U+10FFFF。大多数平面是文字,特殊用意的区段集中在几个平面里。
| 范围 | 名称 | gc | 用途 | JS 属性类 |
|---|---|---|---|---|
U+D800–U+DFFF |
High / Low Surrogates | Cs |
UTF-16 代理对专用,单独非法 | 是 \p{Cs} |
…FDD0–…FDEF 与每平面末 …FFFE/…FFFF |
Noncharacters(66 个) | Cn |
保留给程序内部,永不分配 | 是 \p{Noncharacter_Code_Point} |
U+E000–U+F8FF |
Private Use Area | Co |
标准永不定义,留给私下约定 | 是 \p{Co} |
U+F0000–U+FFFFD / U+100000–U+10FFFD |
Supplementary PUA-A / B | Co |
两整个平面的私用区 | 是 \p{Co} |
U+FFFD |
Replacement Character � | So |
解码失败时的回退占位 | 普通符号 |
U+202A–U+202E / U+2066–U+2069 |
Bidi 方向控制 | Cf |
改变显示方向 → Trojan Source | 是 \p{Cf} |
U+0000 / U+10FFFF |
码空间首 / 尾 | — | 边界:第一个 / 最后一个码点 | — |
警示 · U+10FFFF 有双重身份:它既是码空间的最后一个码点,本身又是一个非字符(noncharacter)——每个平面最后两个码点(…FFFE / …FFFF)和 U+FDD0~U+FDEF 一起,共 66 个非字符,永久保留给程序内部当哨兵或标记,永不分配给真正的字符。
3 · 这些码点在 JS 里的真实行为
前两节讲的是「身份」,本节是「行为」——四个最常撞见的特殊码点,数值全是当场算出来的。
4 · 番外:花钱「赞助」一个字符
一个常见误解:「私用区是不是 Unicode 卖给或留给赞助商的?」——不是。私用区是谁都能用的公共空白,标准只承诺永不在那里放官方字符,含义靠私下约定,没有谁能买断。真正和「赞助」有关的是另一件事:Unicode Consortium 的 Adopt a Character 募捐项目。
注 · Adopt a Character(认领一个字符)是给 Unicode 捐一笔款,「认领」一个早已编码、人人都在用的公共字符,换来一张电子徽章加证书和官网致谢——不会拿到 code point,也没有任何所有权,那个字符照旧属于标准、归大家共用。分三档:Gold $5,000(某字符唯一赞助人)、Silver
$1,000(最多 5 人)、Bronze $100。所以它和私用区 PUA 是两码事:PUA 是「公共空白、私下约定」,Adopt 是「给标准组织捐款、领证书」。官方页面见 aac.unicode.org/adopt 与 赞助人名单。
建议 · 和别的页串起来看:代理区为什么是「孤儿」,见 字符的编码 的代理对换算;单用的 Regional Indicator 怎么两两拼成国旗,见 RGI 序列;零宽与 BOM 这类「看不见但有空白语义」的字符,见 空白与换行。
5 · 参考文献
- Unicode. FAQ: Private-Use Characters, Noncharacters & Sentinels. 私用区与非字符的用途、为什么标准保证永不分配。unicode.org
- Boucher, N. & Anderson, R. Trojan Source(CVE-2021-42574). bidi 控制符怎么让源码「看的和编译的不一样」。trojansource.codes
- Unicode. Full Emoji List. 逐码点查证各平台对国旗等序列的真实渲染。unicode.org