Usar la normalización Unicode para representar cadenas

Las aplicaciones pueden usar Unicode para representar cadenas en varios formularios. A medida que la aceptación de Unicode ha crecido, especialmente a través de Internet, ha surgido la necesidad de eliminar las diferencias no esenciales en las cadenas Unicode. Varias representaciones para una combinación de caracteres complican el software, por ejemplo, cuando un servidor web responde a una solicitud de página o un enlazador busca un identificador determinado en una biblioteca.

Precaución

Las diferentes cadenas Unicode pueden parecer idénticas visualmente, lo que plantea problemas de seguridad. Para obtener más información, vea Consideraciones de seguridad: Características internacionales.

 

En respuesta a este requisito, el Consorcio Unicode ha definido un proceso denominado "normalización", que genera una representación binaria para cualquiera de las representaciones binarias equivalentes de un carácter. Una vez normalizado, dos cadenas son equivalentes si y solo si tienen representaciones binarias idénticas. La normalización elimina algunas diferencias, pero conserva las mayúsculas y minúsculas.

Para usar la normalización Unicode, una aplicación puede llamar a las funciones NormalizeString e IsNormalizedString para reorganizar las cadenas que se acumulan en Unicode 4.0 TR#15. La normalización puede ayudar a mejorar la seguridad reduciendo las representaciones de cadena alternativas que tienen el mismo significado lingüístico. Recuerde, sin embargo, que la normalización no puede eliminar representaciones alternativas por completo.

Para obtener una descripción detallada de los estándares Unicode para la normalización, consulte el Anexo estándar unicode n.º 15: Formularios de normalización Unicode (UAX #15).

Precaución

Dado que la normalización puede cambiar la forma de una cadena, los mecanismos de seguridad o los algoritmos de validación de caracteres normalmente deben implementarse después de la normalización. Para obtener más información, vea Consideraciones de seguridad: Características internacionales.

 

Proporcionar varias representaciones de la misma cadena

En muchos casos, Unicode permite varias representaciones de lo que es, lingüísticamente, la misma cadena. Por ejemplo:

  • El mayúscula A con dieresis (umlaut) se puede representar como un único punto de código Unicode "Ä" (U+00C4) o la combinación de Mayúscula A y el carácter dieresis combinado ("A" + " ́", es decir, U+0041 U+0308). Se aplican consideraciones similares para muchos otros caracteres con marcas diacríticas.
  • El capital A se puede representar de la manera habitual (letra mayúscula latina A, U+0041) o por letra mayúscula latina completa A (U+FF21). Se aplican consideraciones similares a las demás letras latinas simples (mayúsculas y minúsculas) y para los caracteres katakana usados en la escritura en japonés.
  • La cadena "fi" se puede representar mediante los caracteres "f" e "i" (U+0066 U+0069) o por la ligadura "fi" (U+FB01). Se aplican consideraciones similares a muchas otras combinaciones de caracteres para las que Unicode define ligaduras.

Usar los cuatro formularios de normalización definidos

Las aplicaciones pueden realizar la normalización Unicode mediante varios algoritmos, denominados "formularios de normalización", que obedecen a reglas diferentes. El consorcio Unicode ha definido cuatro formas de normalización: NFC (formulario C), NFD (formulario D), NFKC (formulario KC) y NFKD (formulario KD). Cada formulario elimina algunas diferencias, pero conserva las mayúsculas y minúsculas. Win32 y .NET Framework admiten los cuatro formularios de normalización.

El tipo de enumeración NLS NORM_FORM admite los cuatro formularios de normalización Unicode estándar. Los formularios C y D proporcionan formularios canónicos para cadenas. Las formas no canónicas KC y KD proporcionan mayor compatibilidad y pueden revelar ciertas equivalencias semánticas que no son aparentes en las formas C y D. Sin embargo, lo hacen a costa de una determinada pérdida de información y, por lo general, no se deben usar como una manera canónica de almacenar cadenas.

De las dos formas canónicas, la forma C es un formulario "compuesto" y el formulario D es un formulario "descomponido". Por ejemplo, el formulario C usa el único punto de código Unicode "Ä" (U+00C4), mientras que el formulario D usa ("A" + " ́", es decir, U+0041 U+0308). Se representan de forma idéntica, porque " ́" (U+0308) es un carácter combinado. El formulario D puede usar cualquier número de puntos de código para representar un único punto de código utilizado por el formulario C.

Si dos cadenas son idénticas en la forma C o en la forma D, son idénticas en el otro. Además, cuando se representa correctamente, se muestran indistinguiblemente entre sí y de la cadena no normalizada original.

Una vez normalizado, las cadenas no se pueden devolver de forma coherente a su representación original. Por ejemplo, si una cadena con una mezcla de representaciones de caracteres compuestas y descomponidas se convierte en un formulario normalizado, no hay ninguna manera de anular la normalización de la cadena mixta original. Por lo tanto, si una aplicación requiere la representación original de la cadena, debe almacenar esa representación explícitamente. Sin embargo, la conversión entre las dos formas canónicas es reversible. Se puede convertir una cadena en el formulario C en el formulario D y, a continuación, volver al formulario C, y el resultado es idéntico a la cadena de forma C original.

Los formularios KC y KD son similares a los formularios C y D, respectivamente, pero estos "formularios de compatibilidad" tienen asignaciones adicionales de caracteres compatibles con la forma básica de cada carácter. Estas asignaciones pueden hacer que se pierdan variaciones de caracteres menores. Combinan determinados caracteres que son visualmente distintos. Por ejemplo, combinan caracteres de ancho completo y medio ancho con el mismo significado semántico, o formas diferentes de la misma letra árabe, o la ligadura "fi" (U+FB01) y el par de caracteres "fi" (U+0066 U+0069). También combinan algunos caracteres que a veces pueden tener un significado semántico diferente, como un dígito escrito como superíndice, como un subíndice o entre un círculo. Debido a esta pérdida de información, los formularios KC y KD generalmente no deben usarse como formas canónicas de cadenas, pero son útiles para determinadas aplicaciones.

El formulario KC es un formulario compuesto y el KD de formulario es un formulario descomponido. La aplicación puede retroceder y avanzar entre los formularios KC y KD, pero no hay ninguna manera coherente de pasar de la forma KC o KD a la cadena original, incluso si la cadena original está en forma C o D.

Windows, las aplicaciones de Microsoft y .NET Framework suelen generar caracteres en forma C mediante métodos de entrada normales. Para la mayoría de los propósitos de Windows, el formulario C es el formulario preferido. Por ejemplo, los caracteres del formulario C se generan mediante la entrada del teclado de Windows. Sin embargo, los caracteres importados desde la Web y otras plataformas pueden introducir otros formularios de normalización en el flujo de datos.

Los ejemplos siguientes se extraen de UAX n.º 15 e ilustran las diferencias entre las cuatro formas de normalización.

Original Formulario D Formulario C Notas
"Äffin" "A\u0308ffin" "Äffin" El ffi_ligature (U+FB03) no está descomponido, porque tiene una asignación de compatibilidad, no una asignación canónica.${REMOVE}$
"Ä\uFB03n" "A\u0308\uFB03n" "Ä\uFB03n"
"Henry IV" "Henry IV" "Henry IV" El NÚMERO ROMANO IV (U+2163) no está descomponido.${REMOVE}$
"Henry \u2163" "Henry \u2163" "Henry \u2163"
ga ka +ten ga Los distintos equivalentes de compatibilidad de un solo carácter japonés no dan como resultado la misma cadena con el formato C.${REMOVE}$
ka +ten ka +ten ga
hw_ka +hw_ten hw_ka +hw_ten hw_ka +hw_ten
ka +hw_ten ka +hw_ten ka +hw_ten
hw_ka +diez hw_ka +diez hw_ka +diez
kaks k i + a m + ks f kaks Las sílabas hangul se mantienen bajo normalización.

 

Original KD de formulario Formulario KC Notas
"Äffin" "A\u0308ffin" "Äffin" El ffi_ligature (U+FB03) se descompone en forma KC, pero no en forma C.${REMOVE}$
"Ä\uFB03n" "A\u0308ffin" "Äffin"
"Enrique IV" "Enrique IV" "Enrique IV" Las cadenas resultantes aquí son idénticas en forma KC.${REMOVE}$
"Henry \u2163" "Enrique IV" "Enrique IV"
ga ka +diez ga Diferentes equivalentes de compatibilidad de un solo carácter japonés dan como resultado la misma cadena en forma KC.${REMOVE}$
ka +diez ka +diez ga
hw_ka +hw_ten ka +diez ga
ka +hw_ten ka +diez ga
hw_ka +diez ka +diez ga
kaks k i + a m + ks f kaks Las sílabas hangul se mantienen bajo normalización. En versiones anteriores de Unicode, los caracteres jamo como ks f tenían asignaciones de compatibilidad a k f + s f. Estas asignaciones se quitaron en Unicode 2.1.9 para asegurarse de que se mantienen las sílabas hangul.

 

Nota

Las dos tablas anteriores tienen un copyright de © 1998-2006 Unicode, Inc. Todos los derechos reservados.

 

Usar formularios compuestos para glifos únicos

Muchas secuencias de caracteres que corresponden a un solo glifo no tienen formas compuestas. Incluso cuando se normaliza por forma C, un único glifo visual o elemento de texto lógico se puede componer de varios puntos de código Unicode. Por ejemplo, varios caracteres usados en la escritura lituana tienen diacríticos dobles, ya que solo tienen formas descomponidas. Un ejemplo es U en minúsculas con interfaces y tildes ("ū́", U+016b U+0303, donde el primer punto de código es una U minúsculaconl y la segunda es un énfasis agudo combinado).

Ejemplo

Puede encontrar un ejemplo relevante en NLS: Ejemplo de normalización Unicode.

Uso de la compatibilidad con idiomas nacionales

Consideraciones de seguridad: Características internacionales

IsNormalizedString

NormalizeString