Nuestros programadores estrellas agotaron sus depósitos de café, en su búsqueda día y noche por la respuesta, hasta que Alicia encontró el arreglo en GitLab así que en este momento la comparte con nosotros.
Solución:
ASCII define 128 caracteres, que se asignan a los números del 0 al 127. Unicode define (menos de) 221 caracteres, que, de manera similar, se asignan a los números 0-221 (aunque no todos los números están asignados actualmente y algunos están reservados).
Unicode es un superconjunto de ASCII y los números del 0 al 127 tienen el mismo significado en ASCII que en Unicode. Por ejemplo, el número 65 significa “A mayúscula latina”.
Debido a que los caracteres Unicode generalmente no caben en un byte de 8 bits, existen numerosas formas de almacenar caracteres Unicode en secuencias de bytes, como UTF-32 y UTF-8.
Comprensión por qué ASCII y Unicode se crearon en primer lugar y me ayudaron a comprender las diferencias entre los dos.
ASCII, Orígenes
Como se indica en las otras respuestas, ASCII usa 7 bits para representar un carácter. Al usar 7 bits, podemos tener un máximo de 2 ^ 7 (= 128) combinaciones distintas*. Lo que significa que podemos representar un máximo de 128 caracteres.
Espera, ¿7 bits? Pero, ¿por qué no 1 byte (8 bits)?
El último bit (octavo) se utiliza para evitar errores como bit de paridad. Esto fue relevante hace años.
La mayoría de los caracteres ASCII son caracteres imprimibles del alfabeto, como abc, ABC, 123,? &!, Etc. Los demás son caracteres de control, como retorno de carro, salto de línea, tabulación, etc.
Vea a continuación la representación binaria de algunos caracteres en ASCII:
0100101 -> % (Percent Sign - 37)
1000001 -> A (Capital letter A - 65)
1000010 -> B (Capital letter B - 66)
1000011 -> C (Capital letter C - 67)
0001101 -> Carriage Return (13)
Vea la tabla ASCII completa aquí.
ASCII fue diseñado solo para inglés.
¿Qué? ¿Por qué solo en inglés? ¡Tantos idiomas por ahí!
Porque el centro de la industria informática estaba en Estados Unidos en ese momento. Como consecuencia, no necesitaban admitir acentos u otras marcas como á, ü, ç, ñ, etc. (también conocidos como diacríticos).
ASCII extendido
Algunas personas inteligentes comenzaron a usar el octavo bit (el bit que se usa para la paridad) para codificar más caracteres para admitir su idioma (para admitir “é”, en francés, por ejemplo). Con solo usar un bit adicional, se duplicó el tamaño de la tabla ASCII original para mapear hasta 256 caracteres (2 ^ 8 = 256 caracteres). Y no 2 ^ 7 como antes (128).
10000010 -> é (e with acute accent - 130)
10100000 -> á (a with acute accent - 160)
El nombre de este “ASCII extendido a 8 bits y no a 7 bits como antes” podría denominarse simplemente “ASCII extendido” o “ASCII de 8 bits”.
Como @Tom señaló en su comentario a continuación, no existe tal cosa como “ASCII extendido”, sin embargo, esta es una manera fácil de referirse a este truco de 8 bits. Hay muchas variaciones de la tabla ASCII de 8 bits, por ejemplo, la ISO 8859-1, también llamada ISO Latin-1.
Unicode, el ascenso
ASCII Extended resuelve el problema de los idiomas que se basan en el alfabeto latino … ¿qué pasa con los demás que necesitan un alfabeto completamente diferente? ¿Griego? ¿Ruso? ¿Chino y similares?
Habríamos necesitado un conjunto de caracteres completamente nuevo … eso es lo racional detrás de Unicode. Unicode no contiene todos los caracteres de todos los idiomas, pero seguro que contiene una cantidad gigantesca de caracteres (consulte esta tabla).
No puede guardar texto en su disco duro como “Unicode”. Unicode es una representación abstracta del texto. Necesita “codificar” esta representación abstracta. Ahí es donde entra en juego una codificación.
Codificaciones: UTF-8 vs UTF-16 vs UTF-32
Esta respuesta hace un buen trabajo al explicar los conceptos básicos:
- UTF-8 y UTF-16 son codificaciones de longitud variable.
- En UTF-8, un carácter puede ocupar un mínimo de 8 bits.
- En UTF-16, la longitud de un carácter comienza con 16 bits.
- UTF-32 es una codificación de longitud fija de 32 bits.
UTF-8 usa el conjunto ASCII para los primeros 128 caracteres. Eso es útil porque significa que el texto ASCII también es válido en UTF-8.
Mnemotécnica:
- UTF-8: mínimo 8 bits.
- UTF-dieciséis: mínimo dieciséis bits.
- UTF-32: mínimo y máximo 32 bits.
Nota:
¿Por qué 2 ^ 7?
Esto es obvio para algunos, pero por si acaso. Tenemos siete espacios disponibles llenos de 0 o 1 (código binario). Cada uno puede tener dos combinaciones. Si tenemos siete lugares, tenemos 2 * 2 * 2 * 2 * 2 * 2 * 2 = 2 ^ 7 = 128 combinaciones. Piense en esto como un candado de combinación con siete ruedas, cada rueda tiene solo dos números.
Fuente: Wikipedia, esta gran publicación de blog y Mocki.co donde publiqué inicialmente este resumen.
ASCII tiene 128 puntos de código, de 0 a 127. Puede caber en un solo byte de 8 bits, los valores de 128 a 255 tienden a usarse para otros caracteres. Con elecciones incompatibles, provocando la página de código desastre. Un programa que asume o adivina otra página de códigos no puede leer correctamente el texto codificado en una página de códigos.
Unicode surgió para resolver este desastre. La versión 1 comenzó con 65536 puntos de código, comúnmente codificados en 16 bits. Posteriormente se amplió en la versión 2 a 1,1 millones de puntos de código. La versión actual es 6.3, usando 110.187 de los 1.1 millones de puntos de código disponibles. Eso ya no cabe en 16 bits.
La codificación en 16 bits era común cuando apareció la versión 2, utilizada por los sistemas operativos de Microsoft y Apple, por ejemplo. Y tiempos de ejecución de lenguajes como Java. La especificación v2 ideó una forma de mapear esos 1,1 millones de puntos de código en 16 bits. Una codificación llamada UTF-16, una codificación de longitud variable en la que un punto de código puede ocupar 2 o 4 bytes. Los puntos de código v1 originales toman 2 bytes, los agregados toman 4.
Otra codificación de longitud variable que es muy común, utilizada en los sistemas operativos y herramientas * nix es UTF-8, un punto de código puede tomar entre 1 y 4 bytes, los códigos ASCII originales toman 1 byte y el resto toma más. La única codificación de longitud no variable es UTF-32, toma 4 bytes para un punto de código. No se usa a menudo ya que es bastante derrochador. Hay otros, como UTF-1 y UTF-7, ampliamente ignorados.
Un problema con las codificaciones UTF-16/32 es que el orden de los bytes dependerá del endian-ness de la máquina que creó el flujo de texto. Así que agregue a la mezcla UTF-16BE, UTF-16LE, UTF-32BE y UTF-32LE.
Tener estas diferentes opciones de codificación trae de vuelta el desastre de la página de códigos hasta cierto punto, junto con acalorados debates entre los programadores sobre cuál opción UTF es la “mejor”. Su asociación con los valores predeterminados del sistema operativo prácticamente dibuja las líneas. Una contramedida es la definición de una lista de materiales, la marca de orden de bytes, un punto de código especial (U + FEFF, espacio de ancho cero) al comienzo de un flujo de texto que indica cómo se codifica el resto del flujo. Indica tanto la codificación UTF como el endianess y es neutral para un motor de renderizado de texto. Desafortunadamente, es opcional y muchos programadores reclaman su derecho a omitirlo, por lo que los accidentes siguen siendo bastante comunes.