c# - niños - tilde diacritica
Cómo protegerse de diacríticos como el texto de Zalgo (3)
El personaje fotografiado arriba fue tuiteado hace unos meses por Mikko Hyppönen , un experto en seguridad informática conocido por su trabajo sobre virus informáticos y charlas TED sobre seguridad informática. Respecto a SO, solo publicaré una imagen de eso, pero entiendes la idea. Obviamente, no es algo que quieras difundir en tu sitio web y enloquecer a los visitantes.
Tras una inspección adicional, el personaje parece ser una letra del alfabeto tailandés combinada con más de 87 signos diacríticos (¿hay incluso un límite?). Esto me hizo pensar en la seguridad, la localización y cómo se podría manejar este tipo de información. Mi búsqueda me llevó a esta pregunta en Stack, y a su vez una publicación en el blog de Michael Kaplan sobre los signos diacríticos . En él, él demuestra cómo uno puede descomponer una cadena en sus caracteres "base" (simplificados aquí por el bien de la brevedad):
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
Puedo ver cómo esto sería útil en algunos casos, pero en términos de la entrada del usuario, estaría eliminando TODOS los signos diacríticos. Como señala Kaplan, eliminar los signos diacríticos en algunos idiomas puede cambiar completamente el significado de la palabra. Esto plantea la pregunta: ¿cómo se permiten algunos signos diacríticos en la entrada / salida del usuario, pero se excluyen otros casos extremos como el personaje über de Mikko Hyppönen?
¿Hay incluso un límite?
No intrínsecamente en Unicode. Existe el concepto de un formato ''Stream-Safe'' en UAX-15 que establece un límite de 30 combinadores ... En general, no se garantiza que las cadenas Unicode sean Stream-Safe, pero esto podría tomarse como una señal de que Unicode no pretendemos estandarizar nuevos caracteres que requerirían un clúster de grafemas más largo que eso.
30 sigue siendo un montón. El grupo de grafemas de lenguaje natural más largo conocido es el Hakṣhmalawarayaṁ tibetano en 1 base más 8 combiners, por lo que por ahora sería razonable normalizarlo a NFD y rechazar cualquier secuencia de más de 8 combiners en una fila.
Si solo te importan los idiomas comunes de Europa occidental, probablemente puedas reducir eso a 2. Por lo tanto, puedes llegar a un compromiso entre ellos.
Creo que encontré una solución usando NormalizationForm.FormC
lugar de NormalizationForm.FormD
. De acuerdo con MSDN :
[FormC] Indica que una cadena Unicode se normaliza utilizando la descomposición canónica completa, seguida de la sustitución de secuencias con sus compuestos primarios, si es posible.
Supongo que quiere decir que descompone los caracteres en su forma base, y luego los recompone basándose en un conjunto de reglas que permanecen consistentes. Entiendo que esto es útil para fines de comparación, pero en mi caso funciona perfecto. Los caracteres como ü
, é
y Ä
se descomponen / recomponen con precisión, mientras que los caracteres falsos no se pueden recomponer y, por lo tanto, permanecen en su forma base:
Aquí está la expresión regular que debe pescar todos los zalgo, incluidos los omitidos en el rango "normal".
([/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,})
Lo más difícil es identificarlos, una vez que hayas hecho eso, hay multitud de soluciones.
Espero que esto te ahorre algo de tiempo.