2012-08-15 11 views
34

huh?は、Zalgoテキスト

として特殊記号から保護するためにどのように上の写真の文字はMikko Hyppönen、コンピュータウイルスやコンピュータのセキュリティ上のTED talks上の彼の仕事のために知られているコンピュータセキュリティの専門家で数ヶ月前につぶやきました。私はそれをイメージしていますが、あなたはそのアイデアを得ています。明らかにあなたのウェブサイトの周りに広がり、訪問者を驚かせたいとは思わないものです。

さらに検査すると、文字はタイ語のアルファベットの87個以上の発音区別記号と組み合わせて表示されます(制限はありますか?)。これはセキュリティ、ローカリゼーション、そしてこのような入力をどのように処理するかを考えてくれました。私の検索でStackにthis question、マイケル・カプランのブログ投稿はstripping diacriticsになりました。その中で、彼は1つが(簡潔にするためにここに簡略化)その「基盤」の文字に文字列を分解することができる方法を示しています。

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 

私はこれがあることが、いくつかの例において有用であるが、中にする方法を見ることができますユーザーの入力の条件は、すべての発音区別記号を削除します。 Kaplanが指摘しているように、一部の言語で発音区別記号を削除すると、単語の意味が完全に変更される可能性があります。これは疑問を招きます:ユーザの入力/出力にいくつかの発音区別符号を許可しますが、Mikko Hypponnenのような極端なケースを除外する方法はありますか?

+1

静的クラス/ユーティリティクラスを使用してホワイトリストを作成しますか?そして、それはプログラマーに行く価値がある.stackexchange.com。 –

+2

@MonsterTruck、十分に公正だが、ホワイトリストは正確に何か?これらは、私が話しているUnicode文字です。 –

+4

基本文字ごとに最大発音数を設定できます。ベトナムとギリシャ人はまだ大丈夫ですが、非常識なケースを拒否するのに十分なほど高い値を選んでください。 –

答えて

20

も限界があります!

本来Unicodeではありません。 30コンバイナの制限を設定するUAX-15の 'Stream-Safe'フォーマットの概念があります...一般にUnicode文字列はStream-Safeであることは保証されていませんが、これはUnicodeグラフェムクラスターを必要とする新しい文字を標準化しようとはしません。

30まだひどいです。最も長く知られている自然言語の書記素クラスターは、Tibetan Hakṣhmalawarayaṁ(1ベース+ 8コンバイナー)です。したがって、NFDに正規化し、連続して8個以上のコンバイナーのシーケンスを禁止することは合理的です。

一般的な西ヨーロッパ言語のみを扱う場合は、おそらく2に減らすことができます。そのため、それらの間のどこかで潜在的に妥協する可能性があります。

2

NormalizationForm.FormDの代わりにNormalizationForm.FormCを使用して解決策が見つかったと思います。 MSDNによれば:可能であれば

[FormC]

は、Unicode文字列を その一次複合体との配列の置換に続いて、完全 正規分解を用いて正規化されていることを示します。

これは、文字を基本形式に分解し、一貫性のある一連の規則に基づいて文字列を再構成することを意味しています。私はこれを比較目的のために便利ですが、私の場合は完璧に動作します。 üé、及び偽の文字が再構成できないので、その塩基形態のままÄが、正確に再構成/分解されるような文字:

enter image description here

+2

歴史的によく使用される文字に文字列を制限したい場合は、合成文字のみを要求することはOKです。 - Unicodeには、互換性のために従来のエンコーディングで構成されたすべての文字の合成文字が含まれます。ただし、Unicodeへの新しい追加は、分解された形式でしか利用できない場合があります。 – bobince

+0

他のコンバイナを取得するために、SpacingCombiningMarkまたはEnclosingMarkとNonSpacingMarkのチェックを推奨します。また、 'char'を反復することはUTF-16コード単位を越えるので、代理人だけを見るBasic Multilingual Planeの外の文字をチェックすることはできません。正規表現を使用して文字列全体の文字クラスを一度に見つけて置き換えることを提案する。 – bobince

+0

情報ありがとう!これが歴史的によく使われている文字でしか動作しない場合、2〜8コンバイナのキャップを設定する方がはるかに良い解決策のように思えます!あなたのポイントをさらに高めるために、この方法はチベットのシンボルをdownに減らします。それをチベットの僧侶に説明しよう! –

1

Here's regex「正常な」範囲をバイパスしたものを含め、すべてのザルゴを釣り上げる必要があります。

([\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,}) 

最も困難なのは、いったんこれを実行すると、それを識別することです。解決策がたくさんあります。

希望すれば、時間を節約できます。