如何防止诸如Zalgo文本的变音符号

是吧?

上图中的人物是在几个月前由计算机安全专家MikkoHyppönen啾啾 ,他以计算机病毒和TED计算机安全方面的工作而闻名。 关于这个,我只会发表一个形象,但你明白了。 这显然不是你想要传播你的网站,并吓坏游客。

经过进一步的检查,这个angular色似乎是一个泰国字母组合的超过87个变音符号(有甚至是一个限制?!)。 这让我想到安全性,本地化以及如何处理这种input。 我的search引导我在Stack上提出这个问题 ,而Michael Kaplan则发表了一篇关于剥离符号的博客文章。 在这个例子中,他演示了如何将一个string分解为它的“基本”字符(为简洁起见,在这里简化):

StringBuilder sb = new StringBuilder(); foreach (char c in "façade".Normalize(NormalizationForm.FormD)) { if (char.GetUnicodeCategory(c) != UnicodeCategory.NonSpacingMark) sb.Append(c); } Response.Write(sb.ToString()); // facade 

我可以看到这在某些情况下会是有用的,但是在用户input方面,它将删除所有的变音符号。 正如卡普兰指出的那样,删除某些语言的变音符号可以完全改变这个词的含义。 这引出了一个问题: 如何在用户input/输出中允许一些变音符号,但排除其他极端情况,如MikkoHyppönen的人物angular色?

有甚至有限制?

在Unicode中不是本质的。 在UAX-15中有一个“stream安全”格式的概念,设置了30个组合器的限制。一般来说,Unicodestring不保证是stream安全的,但是这当然可以被看作是一个标志,即Unicode不打算标准化新字符,这将需要一个长于这个长度的字形集群。

30还是很可怕的。 已知最长的自然语言字形集群是西藏Hakṣhmalawarayaṁ在1个碱基加8个组合器,所以现在对NFD归一化是合理的,并且不允许连续超过8个组合器的序列。

如果你只关心普通的西欧语言,那么你可能会把它降低到2.所以可能会在两者之间有所妥协。

我想我find了使用NormalizationForm.FormC而不是NormalizationForm.FormD的解决scheme。 根据MSDN :

[FormC]表示使用完全规范分解对Unicodestring进行规范化,如果可能的话,接着用主要的合成代替序列。

我认为这是指将angular色分解为基本forms,然后根据一组保持一致的规则重新组合它们。 我收集这是比较用途,但在我的情况下,它是完美的。 像üéÄ这样的字符被精确地分解/重组,而伪造字符不能重构,因此保持其基本forms:

在这里输入图像说明

这是正则expression式应该淘汰所有的zalgo,包括在“正常”范围内绕过的。

 ([\u0300–\u036F\u1AB0–\u1AFF\u1DC0–\u1DFF\u20D0–\u20FF\uFE20–\uFE2F\u0483-\u0486\u05C7\u0610-\u061A\u0656-\u065F\u0670\u06D6-\u06ED\u0711\u0730-\u073F\u0743-\u074A\u0F18-\u0F19\u0F35\u0F37\u0F72-\u0F73\u0F7A-\u0F81\u0F84\u0e00-\u0eff\uFC5E-\uFC62]{2,}) 

最难的是识别他们,一旦你做到了 – 有很多解决scheme。

希望这可以为你节省一些时间。