unicode encoding utf-8 utf-16

unicode - utf-16 table



¿Qué es Unicode, UTF-8, UTF-16? (8)

¿Cuál es la base de Unicode y por qué es necesario UTF-8 o UTF-16? He investigado esto en Google y he buscado aquí también, pero no lo tengo claro.

En VSS al hacer una comparación de archivos, a veces hay un mensaje que dice que los dos archivos tienen diferentes UTF. Por qué sería este el caso?

Por favor explique en términos simples.


Unicode es un estándar bastante complejo. ¡No tengas mucho miedo, pero prepárate para un trabajo! [2]

Debido a que siempre se necesita un recurso creíble, pero el informe oficial es masivo, sugiero leer lo siguiente:

  1. El Absoluto Mínimo. Todos los desarrolladores de software deben conocer Absolutamente, positivamente los conjuntos de caracteres y Unicode (¡sin excusas!) Una introducción de Joel Spolsky, CEO de Stack Exchange.
  2. Para el BMP y más allá! Un tutorial de Eric Muller, Director Técnico y luego Vicepresidente, en The Unicode Consortium. (primeras 20 diapositivas y ya está)

Una breve explicación:

Las computadoras leen bytes y las personas leen caracteres, por lo que usamos estándares de codificación para asignar caracteres a bytes. ASCII fue el primer estándar ampliamente utilizado, pero solo cubre el latín (7 bits / carácter puede representar 128 caracteres diferentes). Unicode es un estándar con el objetivo de cubrir todos los caracteres posibles en el mundo (puede contener hasta 1,114,112 caracteres, lo que significa 21 bits / máximo de caracteres. Unicode 8.0 actual especifica 120,737 caracteres en total, y eso es todo).

La principal diferencia es que un carácter ASCII puede ajustarse a un byte (8 bits), pero la mayoría de los caracteres Unicode no pueden. Por lo tanto, se utilizan formas / esquemas de codificación (como UTF-8 y UTF-16), y el modelo de caracteres es el siguiente:

Cada carácter ocupa una posición enumerada de 0 a 1,114,111 (hex: 0-10FFFF) llamado punto de código .
Una forma de codificación asigna un punto de código a una secuencia de unidades de código. Una unidad de código es la forma en que desea que se organicen los caracteres en memoria, unidades de 8 bits, unidades de 16 bits, etc. UTF-8 usa de 1 a 4 unidades de 8 bits, y UTF-16 usa 1 o 2 unidades de 16 bits, para cubrir la totalidad de Unicode de 21 bits como máximo. Las unidades usan prefijos para poder detectar los límites de los caracteres, y más unidades significan más prefijos que ocupan bits. Entonces, aunque UTF-8 usa 1 byte para el script latino, necesita 3 bytes para los scripts posteriores dentro del Plano Multilingüe Básico, mientras que UTF-16 usa 2 bytes para todos estos. Y esa es su principal diferencia.
Por último, un esquema de codificación (como UTF-16BE o UTF-16LE) mapea (serializa) una secuencia de unidades de código a una secuencia de bytes.

personaje: π
Punto de código: U + 03C0
Formas de codificación (unidades de código):
UTF-8: CF 80
UTF-16: 03C0
esquemas de codificación (bytes):
UTF-8: CF 80
UTF-16BE: 03 C0
UTF-16LE: C0 03

Consejo: un dígito hexadecimal representa 4 bits, por lo que un número hexadecimal de dos dígitos representa un byte
También eche un vistazo a los mapas de planos en Wikipedia para tener una idea del diseño del conjunto de caracteres


¿Por qué necesitamos Unicode?

En los primeros días (no demasiado), todo lo que existía era ASCII. Esto estaba bien, ya que todo lo que se necesitaría alguna vez serían algunos caracteres de control, puntuación, números y letras como los de esta oración. Desafortunadamente, el extraño mundo de la intercomunicación global y las redes sociales de hoy no estaba previsto, y no es tan inusual ver inglés, العربية, 汉语, עִבְרִית, ελληνικά, y ភាសាខ្មែរ en el mismo documento (espero que no haya roto ningún antiguo navegadores).

Pero por el bien de la discusión, digamos que Joe Average es un desarrollador de software. Él insiste en que solo necesitará el inglés, y como tal solo quiere usar ASCII. Esto podría estar bien para Joe, el usuario , pero esto no está bien para Joe, el desarrollador de software . Aproximadamente la mitad del mundo usa caracteres no latinos y el uso de ASCII es posiblemente desconsiderado para estas personas, y además, está cerrando su software a una economía grande y en crecimiento.

Por lo tanto, se necesita un conjunto de caracteres que abarque todos los idiomas. Así llegó Unicode. Asigna a cada carácter un número único llamado punto de código . Una ventaja de Unicode sobre otros conjuntos posibles es que los primeros 256 puntos de código son idénticos a ISO-8859-1 , y por lo tanto también a ASCII. Además, la gran mayoría de los caracteres utilizados comúnmente se pueden representar con solo dos bytes, en una región llamada Plano Multilingüe Básico (BMP) . Ahora se necesita una codificación de caracteres para acceder a este conjunto de caracteres y, como se plantea la pregunta, me concentraré en UTF-8 y UTF-16.

Consideraciones de memoria

Entonces, ¿cuántos bytes dan acceso a qué caracteres en estas codificaciones?

  • UTF-8:
    • 1 byte: estándar ASCII
    • 2 bytes: árabe, hebreo, la mayoría de los guiones europeos (más notablemente excluyendo Georgian )
    • 3 bytes: BMP
    • 4 bytes: todos los caracteres Unicode
  • UTF-16:
    • 2 bytes: BMP
    • 4 bytes: todos los caracteres Unicode

Vale la pena mencionar ahora que los personajes que no están en el BMP incluyen scripts antiguos, símbolos matemáticos, símbolos musicales y caracteres chinos / japoneses / coreanos (RJK) más raros.

Si trabajará principalmente con caracteres ASCII, entonces UTF-8 es ciertamente más eficiente en memoria. Sin embargo, si trabaja principalmente con scripts no europeos, el uso de UTF-8 podría ser hasta 1,5 veces menos eficiente en memoria que el de UTF-16. Cuando se trata de grandes cantidades de texto, como páginas web grandes o documentos de Word largos, esto podría afectar el rendimiento.

Conceptos básicos de codificación

Nota: Si sabe cómo se codifican UTF-8 y UTF-16, pase a la siguiente sección para aplicaciones prácticas.

  • UTF-8: Para los caracteres ASCII estándar (0-127), los códigos UTF-8 son idénticos. Esto hace ideal a UTF-8 si se requiere compatibilidad con versiones anteriores con el texto ASCII existente. Otros caracteres requieren de 2 a 4 bytes. Esto se hace reservando algunos bits en cada uno de estos bytes para indicar que es parte de un carácter de múltiples bytes. En particular, el primer bit de cada byte es 1 para evitar choques con los caracteres ASCII.
  • UTF-16: para caracteres BMP válidos, la representación UTF-16 es simplemente su punto de código. Sin embargo, para caracteres no BMP, UTF-16 introduce pares sustitutos . En este caso, una combinación de dos porciones de dos bytes se asigna a un carácter que no es BMP. Estas partes de dos bytes provienen del rango numérico BMP, pero el estándar Unicode garantiza que no serán válidas como caracteres BMP. Además, dado que UTF-16 tiene dos bytes como su unidad básica, se ve afectado por la endianness . Para compensar, se puede colocar una marca de orden de bytes reservada al comienzo de un flujo de datos que indica la endianidad. Por lo tanto, si está leyendo la entrada UTF-16, y no se especifica ninguna endianidad, debe verificar esto.

Como se puede ver, UTF-8 y UTF-16 no son compatibles entre sí. Así que si estás haciendo E / S, ¡asegúrate de saber qué codificación estás usando! Para obtener más detalles sobre estas codificaciones, consulte las preguntas frecuentes de UTF .

Consideraciones prácticas de programación.

Tipos de datos de caracteres y cadenas: ¿Cómo se codifican en el lenguaje de programación? Si son bytes sin procesar, en el momento en que intente generar caracteres no ASCII, puede tener algunos problemas. Además, incluso si el tipo de carácter se basa en un UTF, eso no significa que las cadenas sean UTF adecuadas. Pueden permitir secuencias de bytes que son ilegales. En general, tendrá que usar una biblioteca que admita UTF, como ICU for C, C ++ y Java. En cualquier caso, si desea ingresar / generar algo distinto a la codificación predeterminada, primero deberá convertirlo.

Codificaciones recomendadas / predeterminadas / dominantes: cuando se le da la opción de qué UTF usar, generalmente es mejor seguir los estándares recomendados para el entorno en el que está trabajando. Por ejemplo, UTF-8 es dominante en la web, y desde HTML5, Ha sido la codificación recomendada . Por el contrario, los entornos .NET y Java se basan en un tipo de carácter UTF-16. Confusamente (e incorrectamente), las referencias a menudo se hacen a la "codificación Unicode", que generalmente se refiere a la codificación UTF dominante en un entorno determinado.

Compatibilidad con bibliotecas: ¿qué codificaciones son compatibles con las bibliotecas que está utilizando? ¿Apoyan los casos de esquina? Como la necesidad es la madre de la invención, las bibliotecas UTF-8 generalmente admiten caracteres de 4 bytes correctamente, ya que los caracteres de 1, 2 e incluso 3 bytes pueden aparecer con frecuencia. Sin embargo, no todas las bibliotecas UTF-16 supuestas admiten pares sustitutos correctamente, ya que ocurren muy raramente.

Contando caracteres: Existen caracteres combinados en Unicode. Por ejemplo, el punto de código U + 006E (n) y U + 0303 (una tilde combinada) forman ñ, pero el punto de código U + 00F1 forma ñ. Deben parecer idénticos, pero un algoritmo de conteo simple devolverá 2 para el primer ejemplo, 1 para el último. Esto no es necesariamente incorrecto, pero puede que tampoco sea el resultado deseado.

Comparando la igualdad: A, А y Α se ven iguales, pero son latinas, cirílicas y griegas respectivamente. También tienes casos como C y, uno es una letra, el otro es un número romano. Además, también tenemos la combinación de personajes a considerar. Para obtener más información, vea Duplicar caracteres en Unicode .

Pares sustitutos: estos aparecen con bastante frecuencia en SO, así que solo proporcionaré algunos enlaces de ejemplo:

¿Otros?:


¿Por qué unicode? Porque ASCII tiene solo 127 caracteres. Los de 128 a 255 difieren en diferentes países, por eso hay páginas de códigos. Así que dijeron que tengamos hasta 1114111 caracteres. Entonces, ¿cómo almacenar el punto de código más alto? Tendrá que almacenarlo con 21 bits, por lo que usará un DWORD que tiene 32 bits con 11 bits perdidos. Entonces, si utiliza un DWORD para almacenar un carácter Unicode, es la forma más fácil porque el valor en su DWORD coincide exactamente con el punto de código. Pero las matrices DWORD son, por supuesto, más grandes que las matrices WORD y, por supuesto, incluso más grandes que las matrices BYTE. Es por eso que no solo hay utf-32, sino también utf-16. Pero utf-16 significa un flujo de PALABRAS, y una PALABRA tiene 16 bits, entonces, ¿cómo puede encajar el punto de código más alto 1114111 en una PALABRA? ¡No puede! Así que ponen todo lo que sea superior a 65535 en un DWORD al que llaman par sustituto. Tales pares sustitutos son dos PALABRAS y pueden ser detectadas mirando los primeros 6 bits. Entonces, ¿qué hay de utf-8? Es una matriz de bytes o un flujo de bytes, pero ¿cómo puede encajar el punto de código más alto 1114111 en un byte? ¡No puede! Está bien, así que ponen también un DWORD ¿verdad? O posiblemente una palabra, ¿verdad? ¡Casi cierto! Inventaron las secuencias utf-8, lo que significa que cada punto de código superior a 127 debe codificarse en una secuencia de 2 bytes, 3 bytes o 4 bytes. ¡Guauu! Pero, ¿cómo podemos detectar tales secuencias? Bueno, todo hasta 127 es ASCII y es un byte único. Lo que comienza con 110 es una secuencia de dos bytes, lo que comienza con 1110 es una secuencia de tres bytes y lo que comienza con 11110 es una secuencia de cuatro bytes. Los bits restantes de estos llamados "bytes de inicio" pertenecen al punto de código. Ahora dependiendo de la secuencia, los siguientes bytes deben seguir. Un byte siguiente comienza con 10, los bits restantes son 6 bits de bits de carga útil y pertenecen al punto de código. Concatene los bits de carga útil del startbyte y el siguiente byte / s y tendrá el punto de código. Esa es toda la magia de utf-8.


Este artículo explica todos los detalles http://kunststube.net/encoding/

ESCRIBIR A BUFFER

si escribe en un búfer de 4 bytes, el símbolo con codificación UTF8, su binario se verá así:

00000000 11100011 10000001 10000010

Si escribe en un búfer de 4 bytes, el símbolo con codificación UTF16, su binario se verá así:

00000000 00000000 00110000 01000010

Como puede ver, dependiendo del idioma que use en su contenido, esto afectará su memoria en consecuencia.

por ejemplo, para este símbolo en particular: enc La codificación UTF16 es más eficiente ya que tenemos 2 bytes de repuesto para usar con el siguiente símbolo. Pero eso no significa que debas usar UTF16 para el alfabeto de Japón.

Lectura de buffer

Ahora, si desea leer los bytes anteriores, debe saber en qué codificación se escribió y decodificarlos correctamente.

por ejemplo, si descodifica esto: 00000000 11100011 10000001 10000010 en codificación UTF16, terminará con no

Nota: La codificación y Unicode son dos cosas diferentes. Unicode es el grande (table) con cada símbolo asignado a un punto de código único. por ejemplo, el símbolo letter (letra) tiene un (punto de código) : 30 42 (hex). La codificación, por otro lado, es un algoritmo que convierte los símbolos en una forma más apropiada, cuando se almacena en hardware.

30 42 (hex) - > UTF8 encoding - > E3 81 82 (hex), which is above result in binary. 30 42 (hex) - > UTF16 encoding - > 30 42 (hex), which is above result in binary.


Originalmente, se pretendía que Unicode tuviera una codificación de 16 bits de ancho fijo (UCS-2). Los primeros usuarios de Unicode, como Java y Windows NT, construyeron sus bibliotecas alrededor de cadenas de 16 bits.

Más tarde, el alcance de Unicode se amplió para incluir caracteres históricos, que requerirían más de 65.536 puntos de código que admitiría una codificación de 16 bits. Para permitir que los caracteres adicionales se representen en plataformas que usaron UCS-2, se introdujo la codificación UTF-16. Utiliza "pares sustitutos" para representar caracteres en los planos suplementarios.

Mientras tanto, muchos de los protocolos de red y software más antiguos usaban cadenas de 8 bits. UTF-8 se creó para que estos sistemas puedan soportar Unicode sin tener que usar caracteres anchos. Es compatible con versiones anteriores con ASCII de 7 bits.


UTF es sinónimo de Unicode Transformation Format. En el mundo actual, existen scripts escritos en cientos de otros idiomas, formatos no cubiertos por el ASCII básico utilizado anteriormente. Por lo tanto, UTF entró en existencia.

UTF-8 tiene capacidades de codificación de caracteres y su unidad de código es de 8 bits, mientras que para UTF-16 es de 16 bits.


Unicode es un estándar que asigna los caracteres en todos los idiomas a un valor numérico particular llamado Puntos de Código . La razón por la que hace esto es porque permite que diferentes codificaciones sean posibles utilizando el mismo conjunto de puntos de código.

UTF-8 y UTF-16 son dos de estas codificaciones. Toman los puntos de código como entrada y los codifican utilizando alguna fórmula bien definida para producir la cadena codificada.

La elección de una codificación particular depende de sus requisitos. Las diferentes codificaciones tienen diferentes requisitos de memoria y, según los caracteres con los que tratará, debe elegir la codificación que utilice la menor cantidad de secuencias de bytes para codificar esos caracteres.

Para obtener más información detallada sobre Unicode, UTF-8 y UTF-16, puede consultar este artículo,

Lo que todo programador debe saber sobre Unicode


  • Unicode
    • Es un conjunto de personajes usados ​​alrededor del mundo.
  • UTF-8
    • una codificación de caracteres capaz de codificar todos los caracteres posibles (llamados puntos de código) en Unicode.
    • unidad de código es de 8 bits
    • use de una a cuatro unidades de código para codificar Unicode
    • 00100100 para " $ " (uno de 8 bits); 11000010 10100010 para " ¢ " (dos de 8 bits); 11100010 10000010 10101100 para " " (tres de 8 bits)
  • UTF-16
    • otra codificación de caracteres
    • unidad de código es de 16 bits
    • use una o dos unidades de código para codificar Unicode
    • 00000000 00100100 para " $ " (uno de 16 bits); 11011000 01010010 11011111 01100010 para "" (dos de 16 bits)