Introducción a las codificaciones
Actualización: noviembre 2007
Internamente, .NET Framework almacena el texto como Unicode UTF-16. Un codificador transforma estos datos de texto en una secuencia de bytes. Un descodificador transforma una secuencia de bytes en este formato interno. Una codificación describe las reglas según las cuales funciona un codificador o un descodificador. Por ejemplo, la clase UTF8Encoding describe las reglas para codificar y descodificar una secuencia de bytes que representa texto como Unicode UTF-8. La codificación y descodificación también pueden incluir algunos pasos de validación. Por ejemplo, la clase UnicodeEncoding comprueba todos los suplentes para asegurarse de que constituyen pares suplentes válidos. Ambas clases se heredan de la clase Encoding.
Elegir una codificación
El estándar Unicode asigna un punto de código (un número) a cada carácter en todos los scripts admitidos. Un Formato de transformación Unicode (UTF) es un método para codificar ese punto de código. Para obtener más información sobre los UTF admitidos por las clases de System.Text, vea Utilizar codificación Unicode, en Unicode en .NET Framework.
Seleccionar una clase de codificación
La clase Encoding es muy general. Las clases admitidas heredadas de Encoding permiten a las aplicaciones de .NET trabajar con las codificaciones comunes que pueden encontrarse en las aplicaciones heredadas, y se puede implementar codificaciones adicionales. Sin embargo, si tiene la oportunidad de elegir, es muy recomendable utilizar una codificación Unicode, normalmente UTF8Encoding o UnicodeEncoding (también se admite UTF32Encoding). Concretamente, se prefiere UTF8Encoding antes que ASCIIEncoding. Si el contenido es ASCII, las dos codificaciones son idénticas, pero UTF8Encoding puede representar todos los caracteres Unicode, mientras que ASCIIEncoding sólo admite los valores de caracteres Unicode entre U+0000 y U+007F. Dado que ASCIIEncoding no proporciona detección de errores, UTF8Encoding también es mejor en cuanto a seguridad.
UTF8Encoding se ha mejorado en materia de velocidad y debería ser más rápida que cualquier otra codificación. Incluso cuando todo el contenido es ASCII, las operaciones realizadas con UTF8Encoding son más rápidas que las operaciones realizadas con ASCIIEncoding. Debe considerar la posibilidad de utilizar ASCIIEncoding sólo para ciertas aplicaciones antiguas. Sin embargo, incluso en este caso, UTF8Encoding podría ser una opción mejor. Dando por hecho que la configuración es la predeterminada, pueden darse los escenarios siguientes:
Si la aplicación tiene contenido interno que no es estrictamente ASCII y se codifica con ASCIIEncoding, cada carácter no ASCII se codifica como un signo de interrogación ("?"). Si la aplicación descodifica después estos datos, la información se pierde.
Si la aplicación tiene contenido que no es estrictamente ASCII y lo codifica con UTF8Encoding, el resultado parece ininteligible si se interpreta como ASCII. Sin embargo, si la aplicación descodifica después estos datos, los datos realizan correctamente un viaje de ida y vuelta (round trip).
Elegir una estrategia de reinterpretación
Cuando una aplicación intenta codificar o descodificar un carácter pero no existe ninguna asignación, debe implementar una estrategia de retroceso, que es un mecanismo de control de errores. Hay dos tipos de estrategias de reinterpretación:
Reinterpretación con ajuste perfecto
Cuando los caracteres no coinciden exactamente en la codificación o descodificación de destino, la aplicación puede intentar asignarlos a un carácter similar.
Reinterpretación con cadenas de reemplazo
Si no hay ningún carácter similar adecuado, la aplicación puede especificar una cadena de reemplazo.
Por ejemplo, una aplicación puede llamar a GetEncoding(1252, 0, 0) (vea GetEncoding). Esta llamada especifica la página de códigos 1252 (la página de códigos de Windows para los idiomas de Europa occidental), estableciendo encoderFallback y decoderFallback en cero. El comportamiento predeterminado es una asignación de ajuste perfecto para algunos caracteres Unicode. Por ejemplo, CIRCLED LATIN CAPITAL LETTER S (U+24C8) se cambia a LATIN CAPITAL LETTER S (U+0053) antes de codificarse; SUPERSCRIPT FIVE (U+2075) se cambia a DIGIT FIVE (U+0035). Si la aplicación descodifica después la página de códigos 1252 a Unicode, se pierde el círculo alrededor de la letra y 25 se vuelve 25. Otras conversiones podrían ser aún más drásticas. Por ejemplo, el símbolo de Unicode INFINITY (U+221E) podría asignarse a DIGIT EIGHT (U+0038).
Las estrategias de ajuste perfecto varían en función de la página de códigos, y no se encuentran documentadas de manera detallada. Por ejemplo, para algunas páginas de códigos, los caracteres latinos de ancho completo se asignarán a caracteres latinos de ancho medio, que son más comunes. Para otras páginas de códigos no se realiza esta asignación.
Incluso con una estrategia de ajuste perfecto agresiva, algunos caracteres no tienen un ajuste imaginable en algunas codificaciones. Por ejemplo, un ideograma chino no tiene ninguna asignación razonable en la página de códigos 1252. En ese caso, se utiliza una cadena de reemplazo. De forma predeterminada, esta cadena es simplemente un carácter QUESTION MARK (U+003F).
La asignación de ajuste perfecto es el comportamiento predeterminado para Encoding, que codifica los datos Unicode en datos de página de códigos, y hay aplicaciones antiguas que se basan en este comportamiento. Sin embargo, la mayoría de las aplicaciones nuevas deberían evitarlo por razones de seguridad. Por ejemplo, las aplicaciones no deberían asignar nombres de dominio mediante una codificación de ajuste perfecto.
Sus aplicaciones deben utilizar las alternativas siguientes para las asignaciones de ajuste perfecto:
Para evitar problemas de reinterpretación de caracteres, utilice sólo las codificaciones Unicode (UTF8Encoding, UnicodeEncoding y UTF32Encoding).
Precaución: Aunque UTF7Encoding es técnicamente una codificación Unicode, es menos sólida y segura que otras codificaciones. En algunos casos, cambiar un bit puede modificar radicalmente la interpretación de una cadena UTF-7 completa. En otros casos, es posible que cadenas UTF-7 sustancialmente diferentes codifiquen el mismo texto. Por consiguiente, si puede elegir, no debería utilizar UTF-7. Es preferible UTF-8 a UTF-7.
Utilice EncoderExceptionFallback y DecoderExceptionFallback, que inician la excepción (EncoderFallbackException y DecoderFallbackException, respectivamente) si un carácter no se asigna con exactitud.
Utilice siempre EncoderReplacementFallback y DecoderReplacementFallback para sustituir una cadena de reemplazo si un carácter no se puede asignar exactamente. Éste es el comportamiento predeterminado de ASCIIEncoding. De forma predeterminada, esta cadena es simplemente un signo de interrogación, pero existen métodos que permiten que una aplicación elija una cadena diferente. Aunque suele ser un carácter individual, no es obligatorio. Para DecoderReplacementFallback, que se utiliza al transformar texto en Unicode, un carácter que suele utilizarse es REPLACEMENT CHARACTER (U+FFFD).
Utilice un EncoderFallback o DecoderFallback personalizado para implementar la estrategia preferida. Vea Ejemplo Fallback Encoding Application.
Dos comentarios adicionales acerca de las estrategias de reinterpretación de codificación (o descodificación) con ajuste perfecto:
El ajuste perfecto es básicamente una cuestión de codificación, más que de descodificación. Hay muy pocas páginas de códigos que contengan caracteres que no se puedan asignar correctamente a Unicode. Puesto que no estos caracteres se utilizan normalmente, se han omitido de Unicode.
No hay ningún objeto con nombre compatible que corresponda a los retrocesos de ajuste perfecto. El retroceso de ajuste perfecto de cada página de códigos es distinto. Si la aplicación necesita alternar entre el ajuste perfecto y algún otro retroceso de un objeto Encoding, debe copiar el objeto con ajuste perfecto original en una variable antes de asignar cualquier otro objeto de retroceso. Después, la aplicación podrá recuperar el retroceso de ajuste perfecto volviendo a asignar ese valor a Encoding.EncoderFallback o Encoding.DecoderFallback.
Vea también
Tareas
Ejemplo Fallback Encoding Application
Referencia
Decoding