← 返回字符博物馆
Unicode 实验室

Zalgo 文字为什么会向上下“长毛”?

Zalgo 是在普通基础文字后堆叠大量组合附加符。了解附加符如何定位、为什么正规化不会直接清除它们,以及这种效果会在哪里出问题。

字符显微镜

修改下面的样本,看看屏幕上的内容实际由哪些代码点组成。

每个可见字母后面都跟着多个组合附加符。它们通常不占据独立横向宽度,因此可以堆在同一个位置。

24 个代码点5 个可见单位
  1. U+005A
  2. U+0334
  3. U+0321
  4. U+031B
  5. U+032B
  6. U+0339
  7. U+033F
  8. U+0061
  9. U+0335
  10. U+0321
  11. U+0333
  12. U+030B
  13. U+006C
  14. U+0334
  15. U+0319
  16. U+0313
  17. U+0067
  18. U+0336
  19. U+0324
  20. U+0308
  21. U+006F
  22. U+0337
  23. U+031C
  24. U+033D

Zalgo 文字看起来像字体从行框里逃了出来:

Z̴̡̛̫̹̿a̵̡̳̋l̴̙̓g̶̤̈o̷̜̽

它不是图片,通常也不是字体损坏。这种效果来自在普通基础字符后面添加大量组合附加符

组合附加符在做什么?

许多文字系统需要重音、元音符号、声调、诵读符号以及其他和相邻字符有关的记号。Unicode 把其中很多编码成不占间距的组合字符。

为例,它可以表示为:

  • 单个预组字符 U+00E9 LATIN SMALL LETTER E WITH ACUTE;
  • 或者 U+0065 LATIN SMALL LETTER E,后跟 U+0301 COMBINING ACUTE ACCENT。

第二个代码点会修饰第一个。排版系统把重音放在基础字母上方,却不会像普通字母一样让光标再前进一个字符宽度。

Zalgo 生成器利用了同一机制,只是会在每个字母的上方、下方和中间添加远超正常拼写需要的附加符。

为什么它能堆得这么夸张?

组合字符具有规范组合类别,帮助系统决定它们在基础字符周围的顺序。字体也会为常见组合提供锚点和定位数据。当序列非常少见或特别长时,排版系统只能尽量处理。

一种字体可能把附加符叠得很整齐;另一种可能让它们碰撞、盖住相邻行,或者伸出按钮边界。文字序列本身仍然有效,只是界面从来没有为一个字母上挂几十个重音做过设计。

这也是同一效果会随浏览器和操作系统变化的原因。Unicode 规定字符身份与属性,字体决定具体形状和连接位置。

正规化不等于“删除重音”

Unicode 正规化让等价的文字序列更容易比较。NFC 会在存在预组字符时,把基础字母和附加符组合起来;NFD 则会把许多预组字符拆成基础字符加附加符。两者都会把组合符调整到规范顺序。

但它们都不是通用的 Zalgo 清理器。大多数极端组合根本没有预组等价字符,正规化后,这些附加符依旧是有意义的编码字符。

产品如果想提供“纯净文字”功能,就必须另外决定哪些符号属于语言、哪些属于装饰、哪些可以删除。粗暴移除所有组合符,会损坏越南文、阿拉伯文、希伯来文、印度文字等许多正常语言。

一个视觉字母可以包含很多代码点

Unicode 文本分段通常会把基础字符和后续组合符放进同一个扩展字素簇。所以即使 由两个代码点编码,光标也可以把它当成一个单位移动。

Zalgo 把这条规则推到了极端。一个看起来像单个字母的单位,底层可能有十个、二十个甚至更多代码点。这会影响:

  • 数据库长度限制;
  • 短信和通知截断;
  • 光标移动与选区;
  • 行高和内容裁切;
  • 搜索与内容审核;
  • 屏幕阅读器输出。

用户看到的长度,并不等于计算机存储的长度。

装饰效果背后是重要的文字基础设施

组合附加符不是“坏字符”。它们是数字书写不可缺少的一部分。故障效果之所以成立,正是因为 Unicode 和现代文字塑形系统支持复杂文字,而不是假定每个视觉单位都只是一个英文字母。

风险来自使用场景和数量。巨大的字符堆会让界面难以阅读、制造异常行高,或者隐藏人眼不容易发现但自动系统仍会处理的差异。有关 Unicode 隐形扰动的研究也发现,不可见字符、组合方式、同形字符和文字重排都可能干扰语言处理系统。

怎样使用才不容易破坏页面?

用于装饰性内容时:

  • 把效果限制在一个短标题或一个单词;
  • 使用低到中等强度;
  • 在最终发布的应用中预览;
  • 文字内容很重要时,附上一份普通版本;
  • 不要用于账号、链接、邮箱和安全信息。

产品界面则应同时限制代码点数量和字素簇数量,处理溢出,并测试异常长的组合序列。不能把“看起来很短”理解成“存储和显示成本也很低”。

Zalgo 是靠累积产生的排版效果:基础字母仍然普通,真实的 Unicode 附加符却堆出了不普通的形状。

故障文字生成器可以控制添加多少附加符。建议先从轻度开始,再把结果放到上方显微镜里检查。

资料来源与延伸阅读

  1. 技术规范
  2. 技术规范
  3. 技术规范
  4. 学术论文
    Bad Characters: Imperceptible NLP Attacks

    Nicholas Boucher, Ilia Shumailov, Ross Anderson, and Nicolas Papernot 2022 IEEE Symposium on Security and Privacy 2022 DOI 10.1109/SP46214.2022.9833641

留言反馈

正在加载留言……