2012-08-15 8 views
34

huh?같은 Zalgo 텍스트

Mikko Hyppönen, 컴퓨터 보안에 대한 자신의 컴퓨터 바이러스에 대한 작업과 TED talks 알려진 컴퓨터 보안 전문가가 몇 달 전에 트윗 된 위 그림 문자로 발음 구별 부호를 방지하는 방법. 존경의 의미에서, 나는 단지 그것의 이미지를 게시 할 것이지만 당신은 아이디어를 얻는다. 그것은 분명히 당신이 당신의 웹 사이트 주변에 퍼져 있고 방문자들을 괴롭히는 것을 원하지 않을 것입니다.

추가 검사시 문자는 태국어 알파벳 87 자 이상의 발음 구별 부호와 결합 된 문자로 나타납니다 (한도가 한계입니까?). 이것은 보안, 로컬라이제이션 및 이러한 입력을 처리하는 방법에 대해 생각하게했습니다. Stacking에서 this question으로 검색 한 다음 Michael Kaplan의 블로그 게시물 stripping diacritics에 내 검색을 안내합니다. 방법이 어떤 경우에 유용 할 것입니다,하지만에서

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 Hyppenen과 같은 극단적 인 경우는 제외한다.

+1

정적 클래스/유틸리티 클래스를 통한 화이트리스트? 그리고 그것은 프로그래머들에게 갈 권리가 있습니다 .stackexchange.com. –

+2

@MonsterTruck, 공정하지만, 화이트리스트는 정확히 무엇입니까? 이들은 내가 말하는 유니 코드 문자입니다. –

+4

기본 문자 당 최대 분음 기호 수를 설정할 수 있습니다. 베트남인과 그리스인이 여전히 괜찮으나 미친 경우는 거부 할 수있을 정도로 충분히 높은 가치를 선택하십시오. –

답변

20

도 한계가있다?!

본질적으로 유니 코드가 아닙니다. UAX-15에는 30 개의 결합자를 설정할 수있는 'Stream-Safe'형식의 개념이 있습니다 ... 일반적으로 유니 코드 문자열은 스트림 안전성을 보장하지 않지만 Unicode 문자열은 일반적으로 유니 코드 grapheme 클러스터를 필요로하는 새 문자를 표준화하려고하지는 마십시오.

30 아직 많이 있습니다. 가장 오래된 것으로 알려진 자연어 화장 군은 Tibetan Hakṣhmalawarayaṁ (1 기본 + 8 결합 자)이므로 NFD로 정규화하고 8 개 이상의 결합 자 시퀀스를 연속적으로 허용하지 않는 것이 합리적입니다.

일반적인 서유럽 언어 만 신경 쓰면 아마도 2로 낮출 수 있습니다. 그 사이에 어딘가에서 잠재적으로 타협 할 수 있습니다.

2

NormalizationForm.FormD 대신 NormalizationForm.FormC을 사용하는 해결책을 찾았습니다. MSDN에 따르면 가능한

[FormC]

가 유니 코드 문자열 일차 복합 서열로 교체 한 후, 전체 정규 분해를 사용하여 정규화되는 것을 나타냅니다.

나는 문자를 기본 형식으로 분해 한 다음 일관성있게 유지되는 규칙 집합을 기반으로 문자를 다시 구성한다는 의미입니다. 내가 모으는 것은 비교 목적으로는 유용하지만, 제 경우에는 완벽하게 작동합니다. ü, éÄ 같은 문자는 가짜 문자 따라서 구도, 그리고 실패하면서 기본 형태로 남아 정확하게 재구성/분해 :

enter image description here

+2

문자열을 역사적으로 일반적으로 사용되는 문자로 제한하려면 구성된 문자 만 필요합니다. 유니 코드는 호환성을 위해 레거시 인코딩으로 구성된 모든 문자에 대해 구성된 문자를 포함합니다. 그러나 유니 코드에 새로 추가 된 것은 분해 된 형태로만 사용할 수 있습니다. – bobince

+0

다른 결합자를 얻으려면 SpacingCombiningMark 또는 EnclosingMark뿐만 아니라 NonSpacingMark에 대한 확인을 제안하십시오. 또한'char'에 대한 반복은 UTF-16 코드 단위를 거치므로 대리 언어 만 표시되는 Basic Multilingual Plane 외부의 문자는 확인할 수 없습니다. regex를 사용하여 한 번에 전체 문자열에 대한 문자 클래스를 찾고 바꿀 것을 제안하십시오. – bobince

+0

정보 주셔서 감사합니다! 역사적으로 일반적으로 사용되는 문자에서만 작동하는 경우 2 ~ 8 개 조합의 캡을 설정하는 것이 훨씬 좋은 해결책으로 들립니다. 더 강조하기 위해이 방법은 티베트어 기호를 down로 줄입니다. 티베트 승려에게 설명해보십시오! –

1

Here's regex '정상적인'범위를 우회하는 것을 포함하여 모든 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,}) 

가장 어려운 점은 일단 해결했다면 해결책을 찾을 수 있다는 것입니다.

희망을 보내면 시간을 절약 할 수 있습니다.