¿Por qué hay múltiples codificaciones Unicode?

41

Pensé que Unicode fue diseñado para solucionar el problema de tener muchas codificaciones diferentes debido a un pequeño espacio de direcciones (8 bits) en la mayoría de los intentos anteriores (ASCII, etc.).

¿Por qué entonces hay tantas codificaciones Unicode? Incluso múltiples versiones de la (esencialmente) la misma, como UTF-8, UTF-16, etc.

Matthew Scharley
fuente
11
UTF-8 no es lo mismo que UTF-16. La lista crecerá tan pronto como encontremos otros sistemas solares con planetas similares a la Tierra.
setzamora
1
@Joset: Ya tenemos Klingon. Tenemos la mayoría de los idiomas terrestres en el BMP con un ligero derrame en las llanuras 1,2. Si las teorías actuales son correctas y solo hay 42 especies sensibles en la galaxia que alcanzan un punto en el que pueden usar el viaje espacial (por lo tanto, permiten el primer contacto), deberíamos poder exprimir todos los caracteres en todos los idiomas en UNICODE (suponiendo que podamos expandirnos) de 21 a 22 bits para permitir 64 llanuras). Eso incluso deja 10 bits de espacio de búfer si queremos incluir las especies primitivas que no han logrado el vuelo espacial.
Martin York
77
@ Kevin Hsu: UTF-7,8,16LE, 16BE, 32LE, 32BE. Entonces, existen al menos 6 codificaciones reales. UTF-9 y UTF-18 son tontos de abril.
MSalters
9
Lo bueno de los estándares es que hay muchos de ellos
Homde
1
Vea lo que Spolsky tenía que decir sobre Unicode y la codificación .
MPelletier

Respuestas:

29

Porque la gente no quiere gastar 21 bits en cada personaje. En todos los sistemas modernos, esto esencialmente significaría usar tres bytes por carácter, que es tres veces más de lo que la gente estaba acostumbrada, por lo que no estaban dispuestos a adoptar Unicode. Debían encontrarse compromisos: por ejemplo, UTF-8 es excelente para texto en inglés porque los archivos ASCII heredados no necesitan convertirse en absoluto, pero es menos útil para los idiomas europeos y de poca utilidad para los idiomas asiáticos.

Básicamente, sí, podríamos haber definido una sola codificación universal, así como un solo gráfico de caracteres universal, pero el mercado no lo habría aceptado.

Kilian Foth
fuente
8
+1 Gran respuesta. Para ser sincero, es el único que realmente responde a esta pregunta. Todas las otras respuestas son (más o menos) sobre cómo se distribuyen los bytes en todas las codificaciones Unicode diferentes.
Jacek Prucia
Históricamente es una simple cuestión de desacuerdo. Sin embargo, no veo mucho uso para nada más que UTF-8 hoy, aunque hay escenarios teóricos donde UTF-16 consumiría menos espacio, no es por un gran margen, y son raros. El lugar más destacado en el que desea ahorrar espacio es para los sitios web, pero están llenos de códigos HTML que, con mucho, son más cortos que usan UTF-8. Por ejemplo, podría usar Shift JISpara hacer un sitio web japonés más pequeño que el equivalente UTF-8, pero eso solo funciona porque es un juego de caracteres específicamente para japonés.
aaaaaaaaaaaa
2
No es realmente cierto tampoco. Como los formatos comprimidos realmente solo se utilizan para el transporte y el almacenamiento. Dentro de una aplicación, es más común usar UCS-2 o UCS-4, ya que son de ancho fijo, pero ocupan 2 o 4 bytes por carácter. Por lo tanto, las aplicaciones están dispuestas a renunciar al espacio para la facilidad de uso.
Martin York
but it is less useful for European languages, and of little use for Asian languages- Esto está mal. ¿Por "utilidad" quieres decir compresión? Bueno, entonces UTF-8 proporciona una mejor compresión para los idiomas europeos porque en cada texto hay espacios y signos de puntuación que toman solo un byte.
Nick Volynkin el
37

Unicode es una codificación de caracteres de 21 bits que describe de forma exclusiva "CodePoints", representando cada punto de código mediante un glifo (una representación gráfica).

  • 16 bits utilizados para identificar un punto de código en un plano (la mayoría de los puntos de código están en el plano 0).
  • 5 bits para identificar el plano.

Las codificaciones admitidas son:

  • UTF-8 (para codificar cada punto utilizando valores de 8 bits)
  • UTF-16 (para codificar cada punto utilizando valores de 16 bits)
  • UTF-32 (para codificar cada punto utilizando valores de 32 bits)

Pero no importa cuál sea la codificación cuando decodifica, todos se asignan de nuevo a un punto de código específico que tiene el mismo significado (por lo que es genial).

UTF-8

Este es un formato de tamaño variable. Donde cada punto de código está representado por 1 a 4 bytes.

UTF-16

Este es un formato de tamaño variable. Los puntos de código en el "plano multilingüe básico" (BMP o plano 0) se pueden representar con 1 valor único de 16 bits. Los puntos de código en otros planos están representados por un par sustituto (2 valores de 16 bits).

UTF-32

Este es un formato de tamaño fijo. Todos los puntos de código están representados por un único valor de 32 bits.

Martin York
fuente
2
También me gusta esta respuesta. Estaba escribiendo uno similar, pero este está claro. También agregaría que UTF-8 también es útil porque las cadenas ASCII son automáticamente UTF-8.
Kevin Hsu
44
Por favor, es el plano multilingüe básico , no un plano .
JSB ձոգչ
3
Esta es una buena respuesta, pero creo que todavía plantea la pregunta "¿Por qué?", ​​Aunque esta respuesta implícitamente toca eso. Para elaborar: UTF-32 es un enfoque más directo (algunos dirían más fácil) de codificar caracteres Unicode, pero también desperdicia mucho espacio, ya que cada carácter ocupa 4 bytes. UTF-8 es mucho más compacto y retrocompatible con ASCII, pero no es regular: un personaje puede tomar de 1 a 4 bytes para codificar, lo que hace que sea más difícil trabajar con él. UTF-16 es una especie de enfoque híbrido entre los dos, principalmente con los pros y los contras de cada uno.
mipadi
44
Existe una compensación entre el uso de la memoria (donde UTF-8 es mejor, ya que los caracteres más comunes son de un solo byte) y la velocidad de procesamiento (donde UTF-32 es mejor, porque todos los caracteres son del mismo tamaño, lo que permite ciertas optimizaciones y brinda una perfecta Alineación de 32 bits en la memoria). Como resultado, los protocolos de red y los formatos de archivo suelen usar UTF-8 (para ahorrar ancho de banda / espacio de almacenamiento), mientras que los intérpretes de guiones y los tiempos de ejecución del idioma pueden preferir UTF-16 o UTF-32.
tdammers
2
@Marcel: Un "CodePoint" es un "CodePoint" no un character(ya que un carácter puede construirse a partir de múltiples "CodePoints"). No confunda los dos términos. Pero tienes razón "CodePoints" no se refieren a glifos. Un glifo es solo una representación gráfica de un punto de código. Una diferencia sutil pero importante.
Martin York
25

Creo que es útil separar las 2 ideas:

  1. Unicode: asignación de personajes de todo el mundo a puntos de código.
  2. Codificación: asignación de puntos de código a patrones de bits (UTF-8, UTF-16, etc.).

UTF-8, UTF-16 y otras codificaciones tienen sus propias ventajas y desventajas. Mejor consulte Wikipedia al respecto.

jfs
fuente
@jfs: ¿Por qué tener Unicode en absoluto si todavía va a haber una docena o más de codificación diferente que de todos modos son diferentes en el cable? ¿De qué sirve tener un mapeo global en sí mismo?
Matthew Scharley
10
@Matthew Scharley: Lo estás mirando mal. UNICODE asigna todos los caracteres de todos los idiomas (incluido el klingon) a una ID ÚNICA (punto de código). Las codificaciones son simplemente una forma de comprimir los puntos de código en un disco o una secuencia a través de una red. UTF significa "formato de transporte UNICODE". Siempre debe pensar en un punto de código UNICODE como un valor de 21 bits. La ventaja sobre otros formatos es que todos los caracteres están identificados de forma única y no se superponen (a diferencia de Latin-1, Latin-2, etc.).
Martin York
@Matthew Scharley ¿Por qué tener un mapeo global? En realidad, todos tenían su propio mapeo en el pasado (¿recuerdan las páginas de códigos?). Creo que un ejemplo tonto aclarará las cosas. Imagina la idea del amor. ¿Cómo se lo representarás a alguien? ¿Dar flores? Di te amo"? Cada uno tiene su propia forma de expresarlo. El amor (que es una idea abstracta) es como los puntos de código. Expresarlo es como las codificaciones. :)
jfs
44
Unicode es el alfabeto global. UTF-x es la forma en que las computadoras lo transportan, ya que es difícil pasar el papel a través de los cables.
Mel
1
@ Martin, Klingon en realidad no lo logró. Tampoco Tengwar o Cirith, utilizados para escribir lenguas élficas de Tolkein.
TRiG
9

UTF-7, UTF-8, UTF-16 y UTF-32 son simplemente formatos de transformación algorítmica de la misma codificación (puntos de código) de caracteres. Son codificaciones de un sistema de codificación de caracteres.

También son algorítmicamente más fáciles de navegar hacia adelante y hacia atrás que la mayoría de los esquemas anteriores para tratar con juegos de caracteres de más de 256 caracteres.

Esto es muy diferente a la codificación general de glifos por país y a veces por proveedor. Solo en japonés, hubo un montón de variaciones de JIS solo, sin mencionar EUC-JP y la transformación de JIS orientada a la página de códigos que las máquinas DOS / Windows usaban llamada Shift-JIS. (Hasta cierto punto, hubo transformaciones algorítmicas de estos, pero no fueron particularmente simples y hubo diferencias específicas de proveedor en los caracteres que estaban disponibles. Multiplique esto por un par de cientos de países y la evolución gradual de sistemas de fuentes más sofisticados (pantalla verde posterior era), y tuviste una verdadera pesadilla.

¿Por qué necesitarías estas formas de transformación de Unicode? Debido a que muchos sistemas heredados asumieron secuencias de caracteres de 7 bits de rango ASCII, por lo que necesitaba una solución limpia de 7 bits que pasara datos de forma segura a través de esos sistemas, por lo que necesitaba UTF-7. Luego, había sistemas más modernos que podían manejar conjuntos de caracteres de 8 bits, pero los nulos generalmente tenían significados especiales para ellos, por lo que UTF-16 no funcionaba para ellos. 2 bytes podrían codificar todo el plano multilingüe básico de Unicode en su primera encarnación, por lo que UCS-2 parecía un enfoque razonable para los sistemas que iban a ser "conscientes de Unicode desde cero" (como Windows NT y Java VM); entonces las extensiones más allá de eso requerían caracteres adicionales, lo que resultó en la transformación algorítmica de las codificaciones de 21 bits que estaban reservadas por el estándar Unicode, y nacieron pares sustitutos; eso requirió UTF-16. Si tenía alguna aplicación donde la consistencia del ancho de los caracteres era más importante que la eficiencia del almacenamiento, UTF-32 (una vez llamado UCS-4) era una opción.

UTF-16 es lo único que es remotamente complejo de manejar, y eso se mitiga fácilmente por el pequeño rango de caracteres que se ven afectados por esta transformación y el hecho de que las secuencias principales de 16 bits están perfectamente en un rango totalmente distinto del final Secuencias de 16 bits. También es mucho más fácil que tratar de avanzar y retroceder en muchas codificaciones de Asia oriental, donde necesitabas una máquina de estado (JIS y EUC) para lidiar con las secuencias de escape, o potencialmente retroceder varios personajes hasta que encontraras algo garantizado. ser solo un byte inicial (Shift-JIS). UTF-16 también tenía algunas ventajas en los sistemas que podían atravesar secuencias de 16 bits de manera eficiente.

A menos que tenga que vivir a través de docenas (cientos, en realidad) de diferentes codificaciones, o haya tenido que construir sistemas que admitan múltiples idiomas en diferentes codificaciones, a veces incluso en el mismo documento (como WorldScript en las versiones anteriores de MacOs), podría pensar de los formatos de transformación unicode como complejidad innecesaria. Pero es una reducción dramática en la complejidad sobre las alternativas anteriores, y cada formato resuelve una restricción técnica real. También son realmente eficientemente convertibles entre sí, no requieren tablas de búsqueda complejas.

JasonTrue
fuente
1
Las diversas máquinas de estado JIS y EUC son realmente desagradables, y doblemente si estás trabajando con la transformación entre ellas. Unicode simplifica enormemente eso. El único problema importante con Unicode es que ha conseguido dejar de pensar en bytes como caracteres, ASCII usando chovinista pequeña caracteres-setted usted!
Donal Fellows
6

Unicode no fue diseñado para solucionar el problema de tener muchas codificaciones diferentes.

Unicode fue diseñado para solucionar el problema completo de un número que representa muchas cosas diferentes dependiendo de la página de códigos en uso. Los números del 0 al 127 representan los mismos caracteres en cualquier página de códigos Ansi. Esto es lo que también se conoce como el cuadro ASCII o conjunto de caracteres. En las páginas de códigos Ansi, que permiten 256 caracteres, los números 128-255 representan caracteres diferentes en páginas de códigos diferentes.

Por ejemplo

  • El número $ 57 representa una W mayúscula en todas las páginas de códigos, pero
  • El número $ EC representa el símbolo de inifinidad en la página de códigos 437 (EE. UU.), Pero una "LETRA N LATINA PEQUEÑA CON CEDILLA" en la página de códigos 775 (Báltico)
  • El Cent Sign es el número $ 9B en la página de códigos 437, pero el número 96 en la página de códigos 775

Lo que hizo Unicode fue poner todo esto al revés. En Unicode no hay "reutilización". Cada número representa un único personaje único. El número $ 00A2 en Unicode es el signo de centavo y el signo de centavo no aparece en ningún otro lugar en la definición de Unicode.

¿Por qué entonces hay tantas codificaciones Unicode? Incluso múltiples versiones de la (esencialmente) la misma, como UTF-8, UTF-16, etc.

No hay múltiples versiones de la misma codificación. Existen múltiples codificaciones del mismo mapa de definición de caracteres Unicode y se han "inventado" para administrar los requisitos de almacenamiento para diferentes usos de los distintos planos linguales que existen en Unicode.

Unicode define (o tiene el espacio para definir) 4.294.967.295 caracteres únicos. Si desea asignarlos al almacenamiento en disco / memoria sin realizar conversiones algorítmicas, necesita 4 bytes por carácter. Si necesita almacenar textos con caracteres de todos los planos linguales, entonces UTF-32 (que es básicamente una codificación de almacenamiento de 1 carácter - 4 bytes de la definición Unicode) es probablemente lo que necesita.

Pero casi ningún texto usa caracteres de todos los planos linguales. Y luego usar 4 bytes por personaje parece un gran desperdicio. Especialmente cuando se tiene en cuenta que la mayoría de los idiomas en la Tierra se definen dentro de lo que se conoce como el Plano Bilingüe Multilingüe (BMP): los primeros 65536 números de la definición Unicode.

Y ahí es donde entró UTF-16. Si solo usa caracteres del BMP, UTF-16 lo almacenará de manera muy eficiente usando solo dos bytes por carácter. Solo usará más bytes para caracteres fuera del BMP. La distinción entre UTF-16LE (Little Endian) y UTF-16BE (Big Endian) realmente solo tiene algo que ver con cómo se representan los números dentro de la memoria de la computadora (patrón de bytes que A0significa hexadecimal $ A0 o que significa $ 0A).

Si su texto usa aún menos caracteres diferentes, como la mayoría de los textos en idiomas de Europa occidental, tendrá que restringir aún más los requisitos de almacenamiento para sus textos. Por lo tanto, UTF-8, que utiliza un solo byte para almacenar los caracteres presentes en el gráfico ASCII (los primeros 128 números) y una selección de los caracteres Ansi (los segundos 128 números de las diversas páginas de códigos). Solo usará más bytes para caracteres fuera de este conjunto de "caracteres más utilizados".

Entonces para recapitular:

  • Unicode es un mapeo de los caracteres en todos los idiomas en la tierra (y algunos Klingon para arrancar) y luego algunos (matemáticos, musicales, etc.) a un número único.
  • Las codificaciones son algoritmos definidos para almacenar textos utilizando los números de este mapa de caracteres único de la manera más eficiente posible, dado el "uso promedio" de los caracteres dentro de los textos.
Marjan Venema
fuente
2
"Los números del 0 al 127 representan los mismos caracteres en cualquier página de códigos". - bueno, a menos que estés hablando EBCDIC, en cuyo caso $57no es un W
MSalters
@MSalters: tienes toda la razón. EBCDIC es diferente (y hay otros EBCDIC). Supongo que mis días de mainframe han pasado tanto tiempo atrás que no me acordaba, o he reprimido estos recuerdos demasiado y demasiado tiempo ... :-)
Marjan Venema
"Los números del 0 al 127 representan los mismos caracteres en cualquier página de códigos". En realidad, hay codificaciones, como BinarySignWriting, que no son superconjuntos de ASCII. BinarySignWriting, de hecho, no incluye ningún carácter ASCII.
TRiG
@TRiG: Es por eso que edité mi declaración para que sea específicamente sobre las páginas de códigos Ansi. Debe haberlo hecho antes de refrescarte ...
Marjan Venema
Sí. Hubo un comentario adicional y una actualización de la publicación mientras escribía mi comentario. Aún así, BinarySignWriting es interesante.
TRiG
2

Unicode define el mapa entre números y caracteres. Sin embargo, cuando envía un número a un receptor, aún necesita definir cómo representar ese número. Para eso es UTF. Define cómo representar un número en una secuencia de bytes.

Codismo
fuente
2

La razón detrás de UTF-32 es simple: es la representación más directa de los puntos de código Unicode. Entonces, ¿por qué no está todo en UTF-32? Dos razones principales:

Uno es el tamaño . UTF-32 requiere 4 bytes para cada carácter. Para el texto que usa solo caracteres en el Lugar multilingüe básico, esto es el doble de espacio que UTF-16. Para texto en inglés, es 4 veces más espacio que US-ASCII.

La razón más grande es la compatibilidad con versiones anteriores . Cada codificación Unicode que no sea la UTF-32 "sin codificar" fue diseñada para una compatibilidad con un estándar anterior.

  • UTF-8: compatibilidad con versiones anteriores de US-ASCII.
  • UTF-16: compatibilidad con versiones anteriores de UCS-2 (Unicode de 16 bits antes de expandirse más allá del BMP).
  • UTF-7: compatibilidad con servidores de correo no limpios de 8 bits.
  • GB18030: compatibilidad con las codificaciones GB2312 y GBK para chino.
  • UTF-EBCDIC: compatibilidad hacia atrás con el subconjunto latino básico de EBCDIC.

Pensé que Unicode fue diseñado para solucionar el problema de tener muchas codificaciones diferentes

Lo fue, y lo hizo. Es mucho más fácil convertir entre UTF-8, -16 y -32 que lidiar con el antiguo sistema de cientos de codificaciones de caracteres diferentes para diferentes idiomas y diferentes sistemas operativos.

dan04
fuente
1

Usted sabe que un archivo zip puede comprimir un archivo para que sea mucho más pequeño (especialmente texto) y luego descomprimirlo en una copia idéntica del archivo original.

El algoritmo de compresión en realidad tiene varios algoritmos diferentes con diferentes características para elegir: almacenado (sin compresión), Reducido, Reducido (métodos 1-4), Imploded, Tokenizing, Deflated, Deflate64, BZIP2, LZMA (EFS), WavPack, PPMd, donde teóricamente podría probarlos todos y elegir el mejor resultado, pero generalmente solo va con Desinflado.

UTF funciona de la misma manera. Hay varios algoritmos de codificación, cada uno con diferentes características, pero generalmente solo elige UTF-8 porque es ampliamente compatible en comparación con las otras variantes de UTF, lo que a su vez es porque es compatible bit a bit con ASCII de 7 bits, lo que facilita su uso. utilizar en la mayoría de las plataformas informáticas modernas que suelen utilizar una extensión de 8 bits de ASCII.


fuente
ørn: La diferencia con un archivo zip es que hay un encabezado que le indica qué compresión está vigente. Con los archivos de texto, todavía tenemos que adivinar, ¿no?
Matthew Scharley
Hay una secuencia especial que dice exactamente eso. Debido a la compatibilidad con ASCII, es opcional.