Codificación de Caracteres

Submitted by gwolf on Thu, 12/03/2009 - 19:27
TitleCodificación de Caracteres
Publication TypeMagazine Article
Year of Publication2009
AuthorsWolf G
MagazineSoftware Gurú
FrequencyQuarterly
Issue Number26
Pagination48-49
Date Published11/2009
Type of ArticleColumn
ISSN1870-0888
KeywordsASCII, caracteres, codificiación, Unicode, UTF
URLhttp://www.sg.com.mx/content/view/954
Full Text

NOTA: Al preparar este texto, excedí el límite de espacio que me asignan, por lo cual después de terminar de escribir tuve que ver qué párrafos eran más prescindibles. Acá reproduzco el artículo completo, y adjunto como archivo la versión tal cual apareció impresa.

Hace un par de días recibí uno de esos correos que parecen venir de una época ya superada y olvidada hace años: Un correo que comenzaba con la frase:

Para evitar problemas de compatibilidad, este correo no incluye acentos ni enies

En efecto, este problema casi ha desaparecido del correo, y ese pretexto sencillamente ya no resulta ni siquiera una excusa adecuada para quien le da flojera escribir el español correctamente.
Sin embargo, no en todos los campos podemos hablar de un éxito tan grande como en el manejo del correo electrónico — Y es de esperarse. La naturaleza misma del correo lo requiere. Cada mensaje individual debe ser transportado, sin que le sean inflingidas modificaciones por agentes externos, entre los equipos de los participantes en una conversación — que pueden estar configuradas con referentes culturales completamente distintos.
Y si bien para los hispanoparlantes, especialmente para aquellos que sienten que el uso de símbolos internacionales (acentos, tildes y signos de apertura de interrogación/exclamación) es opcional, el correo funcionó casi bien desde un principio (y a continuación detallaremos el por qué), cuando el uso de Internet dio su gran salto cuantitativo en los 1990s y llegó a la población en general, para los nativos de muchas otras culturas alrededor del mundo se hizo imperativo encontrar cómo comunicarse confiablemente.
Pero el problema viene de mucho más atrás. Repasemos rápidamente la historia de los esquemas de codificación de caracteres.

Repaso histórico

La codificación a partir de la cual se originan todos los esquemas en uso hoy en día nació en 1963, revisado/ratificado en 1967 con el nombre de ASCII: Código Estándar Americano para el Intercambio de Información. ASCII es un código de 7 bits, permitiendo la representación de hasta 128 caracteres, y en su versión definitiva incluye 32 caracteres de control, 34 símbolos, 52 caracteres de texto (mayúsculas y minúsculas) y 10 dígitos.
Sobra decir que el ámbito cómputo ha cambiado drásticamente desde 1963. La computadora debía representar apenas la información indispensable para ser comprendida por sus operadores, y en la propuesta original, ASCII no incluía ni siquiera letras minúsculas . Pero ya en 1964 aparecieron las máquinas de escribir IBM MT/ST: Una máquina de escribir electrónica, con la capacidad de guardar (y corregir) páginas en cinta magnética. Fue sólo cuestión de tiempo (y del necesario paso de popularización que siguió a la revolución de las computadoras personales hacia fines de los 1970) para que estas capacidades quedaran al alcance de todo mundo.
Y es ahí donde se hizo obvio que haría falta extender ASCII: Todos los idiomas europeos que utilizan el alfabeto latino a excepción del inglés requieren de diferentes tipos de diacríticos para ser representados; tras varias ideas descartadas, se aprovechó el hecho de que hacia fines de los 1970 todas las computadoras ampliamente desplegadas tenían un tamaño de palabra de 8 bits para utilizar un ASCII ampliado que daría 128 caracteres adicionales. Sin embargo, la idea resonó rápidamente… Y no surgió un estándar para su uso. Además, muchos de estos caracteres fueron empleados para incluir caracteres gráficos, para permitir construir interfaces amigables al usuario.
En 1981, IBM puso a la venta su primer computadora personal - La IBM 5051, o como se popularizó, la PC. Entre sus características contaba con una tarjeta de video con páginas de códigos reprogramables — La mitad superior del espacio de caracteres podía ser definida por software; los caracteres cargados por omisión eran los de la página de códigos 437 (CP437), con soporte parcial para algunos lenguajes europeos, pero –debido al espacio empleado por los caracteres semigráficos para representar interfaces al usuario– nunca fueron suficientes, por lo que en general era necesario activar una página de código alternativa — Para el español, la CP850. La situación mejoró al popularizarse los entornos gráficos y dejar de depender de los caracteres semigráficos; varias hojas de código relacionadas pudieron agruparse en un menor número — En este caso, para lenguajes europeos occindentales, la ISO-8859-1.
El problema se presenta al intercambiar archivos con usuarios de otras páginas: Los datos que usan una página son indistinguibles que los que usan otra. Si compartiera un archivo ISO-8859-1 con una persona de Europa oriental (ISO-8859-2), los caracteres acentuados aparecerían modificados, aparentemente corruptos. La situación de los lenguajes de Asia oriental era mucho peor aún, dado que por la cantidad de glifos, plantear el uso de un alfabeto de 256 caracteres resultó imposible — y por muchos años, la interoperabilidad fue meramente un sueño.
En 1988, Joe Becker, Lee Collins y Mark Davis, de Xerox y Apple, se reunieron para atacar este problema de raiz: Lanzaron la iniciativa del sistema Unicode, buscando aprovechar los grandes avances de más de 20 años del cómputo para lograr un conjunto de caracteres apto para todo el mundo. Pronto su iniciativa logró captar la atención y el respaldo de otros líderes del desarrollo del cómputo.
El desarrollo de Unicode no está libre de desaciertos y peleas políticas, pero el resultado bien lo valió: Para 1996 se publicó la especificación Unicode 2.0, permitiendo un espacio de más de un millón (216+220) de puntos de código independientes, reteniendo compatibilidad hacia atrás completa con el principal esquema heredado (ISO-8859-1), derivado de CP850.
Unicode es tan grande que su representación interna no está libre de polémica e interpretaciones. Sin entrar en detalles técnicos, las dos principales representaciones son UTF-8 (utilizada en sistemas basados en Unix, y en general, para toda transmisión sobre redes de datos) y UTF-16, descendiente de UCS-2 (en uso principalmente en sistemas Windows).
No entraré mucho en detalles respecto a estas dos representaciones — Es sólo importante estar conscientes de que una cadena Unicode puede estar representada internamente de diferentes maneras; UTF-8 está basado en elementos individuales de 8 bits, mientras que el átomo en UTF-16 es de 16 bits, por lo que –especialmente con idiomas basados en el alfabeto latino– UTF-8 es más compacto (con UTF-16, el byte superior consistirá sólamente de ceros) y es sensiblemente más robusto para transmisiones sobre la red (una corrupción de datos afecta un punto mínimo, mientras que con UTF-16 puede hacer ilegible todo el texto a partir de ese punto).
Un punto importante a mantener en cuenta es que la representación binaria de texto ASCII heredado es idéntica a su representación en UTF-8 — No así con UTF-16. Para más detalles respecto a estas dos representaciones, así como las otras varias posibles, sugiero leer (Wikipedia Comparación).

¿Qué hace diferente al tratamiento de Unicode?

Hasta antes de Unicode, todo lo que teníamos que saber respecto a un esquema de codificación se limitaba a elegir la salida adecuada, o interpretar la entrada como debía ser. Y Unicode agrega muchos puntos a la mezcla. algunos de ellos:

Longitud de una cadena
Como programadores, estamos acostumbrados a que la longitud caracteres de una cadena es igual a su tamaño entes. Unicode rompe con este supuesto — Para medir langitud ahora tenemos que evaluar la cadena completa ycontrar cuáles partículas son de qué tamaño — Un caracterede medir entre uno y seis bytes, y hay además caracteresm>combinantes, que no ocupan un espacio por sí sólosno que modifican al anterior.
No todas las cadenas son válidas
Con los esquemas tradicionales de 8 bits, todo conjunto deracteres es válido. Al hablar de las representaciones deicode, hay cadenas que resultan inválidas.
Si han visto una página Web donde los caracteres con diacríticos aparecen substituídos por caracteres en forma de rombo con un signo de interrogación dentro (�, punto de código U+FFFD), éste caracter denota que el procesamiento de Unicode no pudo completarse. Sin embargo, no todas las aplicaciones son tan benignas como un navegador — Una base de datos, por ejemplo, debe negarse a guardar datos mal-formados, por lo cual debemos estar conscientes del tipo de excepciones que posiblemente recibiremos si nuestro usuario nos da datos inválidos.
Caracteres definidos semánticamente, no visualmente
Los caracteres en Unicode no buscan únicamente representar un grupo de grafías, sino que su significado. En tiempos del ASCII nos acostumbramos a utilizar la representación gráfica más cercana a un caracter. Por ejemplo, nos acostumbramos a representar a la multiplicación con el asterisco ya sea con la letra «x» o con el asterisco; con Unicode podemos usar –cual debe ser– el símbolo ✕ (U+2715). Los alemanes ya no se ven forzados a usar la β (beta griega, U+0392) en vez de la ß (Eszett o S fuerte, U+00DF).
Si bien esto es más una ventaja que nada, puede llevarnos a confusiones. Por ejemplo, si bien en ASCII con CodePage 850 sólo podemos representar a una letra acentuada de una manera (la letra á está en la posición 160), en Unicode puede representarse en este mismo punto, o como la combinación de una a minúscula (caracter 95, U+0061) y un caracter combinante de acento agudo (U+0300): á. Esto permite la gran expresividad que requieren algunos idiomas o alfabetos (ver (Wood 1999-2009) con una clara ejemplificación de la expresividad que otorgan), pero nos obliga a considerar más casos especiales al enfrentarnos a Unicode desde el punto de vista del desarrollador de sistemas.

Promesas, promesas…

Como ya lo hemos discutido en este mismo espacio, el punto que más debemos cuidar como desarrolladores son los puntos de cruce — Las barreras, las costuras en la realidad. Lo ideal sería que no hiciera falta que un componente le dijera explícitamente al otro que está listo y dispuesto para usar Unicode. Un sistema operativo instalado limpiamente el día de hoy, así como casi cualquier aplicación que instalemos sobre de éste, debe funcionar bien –y de manera predeterminada– con Unicode. Claro está, la realidad siempre se interpone — Por un lado, podemos tener que interactuar con componentes heredados. Por otro lado, no podemos olvidar el hecho de que muy rara vez podemos controlar el entorno de nuestros usuarios — Y por último, un punto donde nos toparemos ineludiblemente con problemas de codificación es al hablar con dispositivos externos.
Si bien es posible aplicar reglas heurísticas para determinar si una cadena es válida o no como UTF-8 (Dürst 1997), prácticamente cualquier protocolo que utilicemos hoy en día para transmitir contenido que deba ser interpretado como texto proporciona un campo en su encabezado para indicar el tipo de contenido a utilizar — Sin olvidar tomar en cuenta que muchos protocolos contemplan la transmisión de datos multipartes, ¡y cada una de las partes puede llevar codificaciones diferentes!

Conclusiones

Viendo sólamente estos puntos, puede que muchos de ustedes los vayan poniendo en la balanza, y les parezca que migrar a Unicode es demasiado dificil y no vale la pena. Sin embargo, sencillamente, no nos queda opción: El mundo entero va avanzando en ese sentido.
Si bien nos toca la parte más simple, por ser nativos de una cultura basada en el alfabeto dominante en Internet, no podemos ignorar que formamos parte de un mundo plenamente globalizado, y que los días de vivir en nuestra islita feliz de un sólo alfabeto han terminado.
Del mismo modo que sencillamente ya no es aceptable que una aplicación falle cuando le enviamos datos escritos correctamente acentuados, tampoco es aceptable que rechacemos registrar a personas cuyo nombre tiene origen extranjero, o que tienen una dirección de destinatario no representable con caracteres latinos. Ni es aceptable, en un mundo que tiende a la presentación de software como servicio «en la nube», no ofrecer una solución capaz de manejar los datos enviados por usuarios de todo el mundo es ofrecer una solución con baja calidad de servicio.

Referencias

AttachmentSize
Versión del artículo publicada en la revista1.3 MB
( categories: )