Un sistema de codificación de caracteres (character encoding system) es un esquema asociativo entre un carácter y un determinado código numérico. Es un sistema artificial, creado por convención, que permite transformar de manera inequívoca una secuencia de números o items electrónicos en un valor alfanumérico, sea un carácter propio de un alfabeto u otra clase de signo o valor. Antes de irnos a los sistemas informáticos debemos recordar que estos sistemas de codificación de caracteres tienen precursores históricos que todavía sobreviven entre nosotros. Uno de los sistemas de codificación más conocidos es el Código Morse, que también tuvo una evolución intrínseca antes de adoptar normas internacionales. Los telégrafos utilizaron varios sistemas de codificación antes del conocido sistema de puntos y guiones. Por ejemplo, hubo dispositivos de aguja única que se desviaban a izquierda o derecha, produciendo en el primer caso un sonido seco (dit) al golpear con un tope de marfil y en el segundo, un sonido metálico (dah) al golpear el de metal.
ASCII (American Standard Code for Información Interchange) es un sistema de codificación de caracteres estandarizado basado en el alfabeto latino. Su creación se remonta a 1963 por el ASA (American Standars Association), un comité que anteriormente había estado integrado en el AESC y que posteriormente se reestructuró en la USASI (1966) hasta convertirse en la actual ANSI (American National Standards Institute) a partir de 1969. La ANSI actualmente es miembro de la ISO (International Organization for Standardization). No fue el único creado en aquella época pues también debemos hacer mención del EBCDIC desarrollado por IBM.
El código ASCII utiliza 8 bits (7+1) para representar mediante una serie de dígitos binarios toda una serie de signos, letras y caracteres del alfabeto latino [1]. ASCII utiliza realmente para dicha representación 7 bits ya que el octavo es un bit de paridad para comprobar que la información se ha transmitido sin pérdidas o alteraciones. La forma básica en binario sería 0000 0000. Éste en concreto sería el llamado carácter nulo expresado normalmente con el valor 0 aunque algunas computadoras usaron el 1. Las combinaciones de bits, sin tener en cuenta el primer bit es un bit de paridad, es de 128 (2⁷). Expresados en decimal, sus dígitos irían desde el 0 hasta el 127. Las primeras 31 combinaciones más el carácter final número 127 o DEL corresponden a los llamados caracteres de control, caracteres no imprimibles que indican un tipo de valores predefinidos como Salto de línea, Fin de texto o Acuse de recibo. El resto, del 32 al 126, se corresponde a 94 caracteres imprimibles (incluyendo el espacio). ASCII incluye los siguientes:
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{}|~
El carácter Espacio también es imprimible y perceptible de manera análoga al silencio, siendo un vacío entre dos signos. En los sistemas informatizados corresponde al binario 0010 0000. Es importante subrayar que para un carácter determinado tenemos el binario, es decir, la cadena de bits que se representan con una serie de dígitos cuyo valor oscila entre 0 y 1. Cada binario se puede expresar en otro sistema de numeración, bien sea el decimal, el hexadecimal o el octal. El sistema decimal (base 10) es el que todos conocemos, el sistema hexadecimal es también un sistema de numeración posicional pero que toma como base el número 16 y el octal el 8. En el caso de hexadecimal, éste utiliza letras del alfabeto para representar números por encima de 9 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F).
Tomando como ejemplo la letra W mayúscula, se corresponde al binario 1110 1010, 234 en decimal, 352 en octal y EA en hexadecimal. Hay calculadoras y algunos algoritmos para realizar estas conversiones. Pero para añadir un ejemplo haremos la conversión de W a estos sistemas de numeración. Partiremos del binario.
Se multiplica cada valor del decimal por 2 elevado a la posición que le corresponde. Luego se suma el producto de cada multiplicación.
1110 1010 → 1·2⁷+1·2⁶+1·2⁵+0·2⁴+1·2³+0·2²+1·2¹+0·2⁰ = 128+64+32+0+8+0+2+0=234
Se divide el número decimal por 16 (para el hexadecimal) o por 8 (para el octal). Se divide en primer lugar buscando el número entero más grande por el que puede ser dividido. Al lado se añaden los residuos (por ejemplo, dividimos 234 entre 16 y el número entero más grande que nos aparece es el 14. Esto nos da 224. De 234 a 224, la resta nos da 10, éste es el residuo. Si resultado de la división nos permite seguir dividiendo, volveremos a buscar un nuevo número entero. En el primer caso (el hexadecimal) vemos que ya no podemos dividir 16 entre 14 para encontrar un número entero. En cambio, en el octal sí, 29 puede ser dividido de nuevo entre 8, dando como resultado 3.
Posteriormente añadimos los resultados en orden inverso, empezando por el el cociente final y los residuos o restos. En el primer caso tenemos EA, en el segundo 352. Como el sistema hexadecimal representa con un sólo número valores de 16 dígitos, sustituimos éstos por los valores propios. En este caso el 10 equivale a la A y el 14 a la letra E. Por tanto el valor sería EA.
234 / 16 → 1410 → EA 234 / 8 → 352 10 14 2 29 / 8 5 3
Actualmente, para pasar de un sistema a otro podemos usar bien algoritmos específicos o algunas herramientas informáticas. Las calculadoras avanzadas nos permiten realizar dichas conversiones de forma instantánea. No obstante, merece la pena detenerse en el proceso de conversión para entender qué se está haciendo.
El código ASCII permite disponer del alfabeto latino básico (incluyendo mayúsculas y minúsculas), el sistema numérico y algunos símbolos entre los cuales se incluyen algunos signos ortográficos como los signos de puntuación y algunos signos auxiliares. No obstante, como vemos, hay muchos signos que no aparecen representados (doble daga ‡; el signo de negación ¬, el indicador ordinal º), al igual que el sistema de signos diacríticos (que incluye los diferentes sistemas de acentuación) y los caracteres de algunas variaciones y extensiones del alfabeto latino original (Ñ, Ç, Ł, ẞ, Ŧ, Þ, Æ) y de otros alfabetos como el griego o el cirílico. Debido a estas limitaciones y en especial al anglocentrismo, pronto surgió la necesidad de crear otros sistemas de codificación de caracteres más amplios. Las modificaciones del ASCII original son comúnmente llamadas ASCII Extendido porque mantienen los caracteres imprimibles (32 a 126) del ASCII original. La ampliación se podría lograr de dos maneras, sustituyendo algunos valores menos necesarios por otros o usando el bit de paridad para ampliar el número de combinaciones.
En 1972 se creó el ISO/IEC 646 también fijada como ECMA-6. Este sistema de codificación de caracteres optó por la primera vía. La novedad es que incluía una serie de variantes etiquetadas por diferentes códigos especialmente indicadas para el uso internacional (ES-España; FR-Francia; CN-China). El sistema seguía siendo de 7 bits y se logró incluir algunos caracteres más específicos sustituyendo algunos valores del ASCII original, alterando en cada caso los signos de puntuación menos utilizados (‘,»/_-). En la especificación ES (español), por ejemplo, se logró así incluir las vocales con tildes.
En 1987 se creó la ISO-8859, la cual optó por al segunda vía. Esta codificación hacía uso de 8 bits (1 byte) de manera íntegra, logrando aumentar considerablemente las opciones de integración. De esta manera los 128 caracteres originales del ASCII (decimal 0 hasta decimal 127) lograron ampliarse hasta 256 (2⁸), habiendo en total 190 caracteres imprimibles. La ISO-8859 además fue estructurada mediante una serie de 16 partes siendo la ISO-8859-1 la más conocida. Ésta es la que comúnmente se denomina ISO-Latin-1. La novedad de este sistema que es que incorporó al ASCII toda una variedad de caracteres propios del oeste de Europa, incluyendo el español, el francés y el alemán. Con las otras partes (ISO-Latin-2 y sucesivas) se logró agrupar conjuntos de caracteres gráficos de otras culturas y contextos lingüísticos como el arábigo, el tailandés o el cirílico. El griego en concreto se encuentra en la parte 7. El ISO-8859-1 compartió similitudes con otros sistemas de codificación de caracteres de 8 bits como el Mac OS Roman y el Windows-1252 [2] desarrollados por Apple Inc. y Microsoft Corporation respectivamente para sus computadoras.
El gran salto se produce con la llegada del conjunto universal de caracteres. El UCS (Universal Coded Character) surgió a través de la ISO/IEC 10646 y el Unicode. La idea de formar este estándar universal ya venía ideándose desde 1987 aunque la primera versión saldría definitivamente en 1991. Un año antes, ya había sido publicado el primer borrador del ISO/IEC 10646. El proyecto Unicode, mantenido por el UTC (Unicode Technical Committee) guarda una intrínseca relación con el estándar ISO/IEC 10646 ya que desde sus primeras versiones ambos están sincronizados. El Unicode de esta manera es un estándar que permite a su vez emplear tres sistemas de codificación de caracteres basados en 8, 16 y 32 bytes denominados respectivamente UTF-8, UTF-16 y UTF-32. UTF significa Unicode Transformation Format. El primero en aparecer fue el UTF-8. En 1993 se presentó este sistema que utiliza un conjunto de bytes variables que puede ir de 1 a 4 . Recordemos que un byte [3] es un octeto y equivale a 8 bits; por tanto, el sistema podía abarcar los 32 bits. El UTF-8 puede representar un rango de caracteres que se expresan a través de un conjunto de 1, 2, 3 y hasta 4 bytes (8, 16, 24 o 32 bits). Los caracteres posibles no corresponden exactamente al número de bits totales ya que los sistemas UTF utilizan unos bits de marcación para ordenar los distintos conjuntos denominados BOM (Byte Order Mark).
0xxxxxxx 110xxxxx 10xxxxxx 1110xxxx 10xxxxxx 10xxxxxx 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
En el primer conjunto [4] tendríamos un byte, que es lo mismo que tenían los sistemas de codificación de caracteres de 8 bits, las extensiones del ASCII original. Los conjuntos mayores se utilizan para representar respectivamente caracteres romances y alfabetos (como el griego, cirílico, árabe, copto, hebreo entre otros), los caracteres orientales (chino, japonés, coreano) y símbolos matemáticos y alfabetos propios de lenguas muertas. A pesar de este salto cuantitativo respecto a los sistemas previos, el UTF-8 pronto conoció las limitaciones y por ello fue apareció el UTF-16, que haciendo uso también de cadenas de longitud variable, con la posibilidad de usar uno o dos conjuntos de 16 bits (16 o 32 bits), permitía superar el millón de caracteres.
00000xxxxxxxxxxx 110110xxxxxxxxxx 110111xxxxxxxxxx
Por último, la aparición del UTF-32 permitió ampliar la codificación sobremanera. Este sistema de codificación de caracteres hace uso de una longitud fija de 32 bits (4 bytes). No obstante, es el menos implementado de los tres. Los tres sistemas son compatibles en el sentido de que cada carácter tiene un valor inequívoco en cada sistema de codificación de caracteres y por tanto no se solapa con otro. Eso hace que un mismo valor en un sistema pueda ser convertido y leído en otro. No obstante, eso no implica que no puedan haber errores y dificultades, especialmente de cara a los programadores cuando se encuentran con datos que han sido comprimidos o transformados y que no muestran a simple vista los bits de marcación.
UTF-8 → variable → 1/2/3/4 bytes → 8/16/24/32 bit UTF-16 → variable → 2/4 bytes → 16/32 bit UTF-32 → fijo → 4 bytes → 32 bit
Cuando encontramos los documentos oficiales de las listas de caracteres Unicode, podremos ver en un mismo PDF unas tablas (16 columnas x 16 filas cada una) con los códigos de caracteres seguida de una lista con los nombres. En el encabezado aparecerá algo como lo siguiente:
Cuneiform. Range: 12000–123FF
Esto nos indica que el documento en cuestión está destinado a describir los caracteres [5] propios del cuneiforme. La documentación general del Unicode nos ofrecerá más información sobre esto, es decir, para qué sistemas de escritura fue ideado y qué periodos abarca. El conjunto de caracteres del cuneiforme por ejemplo nos permite abarcar lenguas ya extintas como el sumerio, el acadio, el elamita y el hitita. No todos los glifos de una lengua van a estar siempre disponibles especialmente si tenemos en cuenta que muchos todavía están por descubrir. En algunos casos, éstos pueden estar separados en diferentes grupos. Por ejemplo, además del Cuneiforme, es probable que también tengamos que consultar otros documentos aparte ya que se han añadido por separado los sistemas de numeración y puntuación y el cuneiforme de las dinastías tempranas, es decir, caracteres que pertenecen a un estrato cultural muy concreto como los encontrados en Fara y Abu Salabikh.
La documentación oficial en PDF nos mostrará también la versión del Unicode. El que tengo guardado por ejemplo es de la versión 15.1. A veces conviene revisar si hay una documentación nueva ya que continuamente se hacen incorporaciones. El rango indica en qué intervalo se encuentran los valores expresados en hexadecimal. En este caso se usa UTF-32. En este caso hablamos del rango que va desde el hexadecimal 12000 hasta el 123FF. Para indicar el valor en Unicode se suele usar la letra U (por ejemplo, U+12000). Como vemos, el valor binario excede los 8 bits y en una codificación UTF-8 emplearía necesariamente tres palabras o bytes. No obstante, éste aparece en el documento en 32 bits y por tanto, el primer byte o palabra aparece con valores nulos. Para este mismo valor, en UTF-32 bits, el rango de valores quedaría tal que así:
Rango Hexadecimal → 12000 – 123FF Rango decimal → 73728 – 74751 Rango binario → 00000000 00000001 00100000 00000000 – 00000000 00000001 00100011 11111111
El valor del binario en UTF-32 no se corresponden al de UTF-8. Como ya indicamos, a veces se usan bits de marcación. El binario 00000000 00000001 00100000 00000000, quitando los valores nulos sobrantes y añadiendo los bits de marcación (señalados en rojo), quedaría 11110000 10010010 10000000 10000000. Esto puede confundir al principio porque no siempre aparecen los bits marcados. Para los caracteres más utilizados con valores más bajos y cercanos a las variantes europeas, lo normal será utilizar simplemente el UTF-8.
Para añadir un ejemplo, podemos pensar en el valor 1224A (𒉊) y el valor 12081 (𒂁). En la lista final del PDF podemos ver que la etiqueta descriptiva del carácter es CUNEIFORM SIGN NE TIMES UD y CUNEIFORM SIGN DUG respectivamente. Si queremos escribir directamente un carácter como éste podemos instalar en GNU/Linux el paquete Unicode. Tras esto, al pulsar Control+Mayus+u nos aparecerá una u. Entonces debemos escribir el código Unicode correspondiente (el valor en Hex). Tras pulsar espacio o intro, la u desaparecerá y será substituida por el carácter Unicode correspondiente.
Buttu, M. (2020). El gran libro de Python. Marcombo.
Korpela, J. K. (2006). Unicode Explained. O’Reilly Media.
Oliver González, A., Moré López, J., Climent Roca, S. (2011). Traducción y tecnologías. Editorial UOC.
The Unicode Standard Version 15.0
[1] Actualmente el ASCII art también mantiene vivo el conjunto de caracteres original y la moda de crear formas y dibujos mediante la articulación de grafías y signos lingüísticos de mediados de los 70 y principios de los 80.
[2] La utilización de datos en diferentes sistemas de codificación de caracteres, especialmente de cara a la exportación/importación de datos comporta que muchas veces se produzcan errores, especialmente donde hay acentos o caracteres especiales (tipo ñ). Esto ocurre cuando se importan datos de la web codificados mediante Unicode y se manejan desde programas nativos de Windows que usan el Windows-1252. Esta codificación nativa de Windows, en su conjunto, es nombrada a veces como ANSI y nació como un intento de estandarización nacida en el mercado estadounidense.
[3] Como dato curioso podemos indicar que la palabra byte tiene su origen en Werner Buchholz, ingeniero electrónico que usó la expresión bite of bit en 1956 para designar ese pequeño conjunto de 8 bits (bocadito o mordisquito de bits) con los que operaba la computadora. El término se empleó en y para evitar la confusión con la i latina de bit.
[4] Esos conjuntos de bytes son denominados «palabras» en muchos contextos informáticos ya que se suelen representar los bites que conforman un byte juntos, separados por un espacio del byte siguiente.
[5] Durante el texto utilizo el término carácter para referirme a las diferentes letras, signos y marcas que utiliza un alfabeto o sistema de escritura determinado. Hay que tener en cuenta que el Unicode abarca no sólo signos o scripts propios de un sistema de escritura sino también números, símbolos, glifos, grafemas, emoticonos y otros códigos de expresión digital.
Richard Sandler (1946), Subway Noir, NYC, 1986 Siguiendo el escurridizo sendero que conduce al mundo… Leer más
Under The Waves es un videojuego de aventura narrativa desarrollado por Parallel Studio y editado… Leer más
GrapheneOS He decidido hacer esta guía porque recientemente conseguí instalar GrapheneOS en un móvil Pixel… Leer más
Jakub Hadrava, St George's Church in the Czech village of Lukova (mod. from Bousure) «Uno… Leer más
Lacrimosa es un grupo musical fundado en Suiza en 1990 por Tilo Wolff. El grupo,… Leer más
Trinity College, Dublin, Ireland Esta guía MLA es una introducción general realizada para una consulta… Leer más