¿Qué son Unicode, UTF-8 y UTF-16?

Resuelto SoftwareGeek asked hace 14 años • 0 respuestas

¿Cuál es la base de Unicode y por qué es necesario UTF-8 o UTF-16? Investigué esto en Google y busqué aquí también, pero no me queda claro.

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

Por favor explique en términos simples.

SoftwareGeek avatar Feb 11 '10 07:02 SoftwareGeek
Aceptado

¿Por qué necesitamos Unicode?

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

Pero a modo de argumento, digamos que Joe Average es un desarrollador de software. Insiste en que sólo necesitará inglés y, como tal, sólo quiere utilizar ASCII. Esto podría estar bien para Joe, el usuario , pero no está bien para Joe, el desarrollador de software . Aproximadamente la mitad del mundo usa caracteres no latinos y se puede decir que usar ASCII es desconsiderado para estas personas, y además de eso, 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í surgió 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 tanto, también a ASCII. Además, la gran mayoría de los caracteres utilizados habitualmente son representables mediante sólo dos bytes, en una región denominada Plano Multilingüe Básico (BMP) . Ahora se necesita una codificación de caracteres para acceder a este conjunto de caracteres y, como plantea la pregunta, me concentraré en UTF-8 y UTF-16.

Consideraciones de memoria

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

  • UTF-8:
  • 1 byte: ASCII estándar
  • 2 bytes: árabe, hebreo, la mayoría de las escrituras europeas (sobre todo excluyendo el georgiano )
  • 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 caracteres que no están en el BMP incluyen escrituras antiguas, símbolos matemáticos, símbolos musicales y caracteres chinos, japoneses y coreanos (CJK) más raros .

Si va a trabajar principalmente con caracteres ASCII, entonces UTF-8 es sin duda más eficiente en cuanto a memoria. Sin embargo, si trabaja principalmente con scripts no europeos, usar UTF-8 podría ser hasta 1,5 veces menos eficiente en memoria que UTF-16. Cuando se trabaja con grandes cantidades de texto, como páginas web de gran tamaño o documentos de texto extensos, 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 que UTF-8 sea ideal si se requiere compatibilidad con texto ASCII existente. Otros caracteres requieren entre 2 y 4 bytes. Esto se hace reservando algunos bits en cada uno de estos bytes para indicar que es parte de un carácter multibyte. En particular, el primer bit de cada byte sirve 1para evitar conflictos 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 que no son 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 porciones de dos bytes provienen del rango numérico BMP, pero el estándar Unicode garantiza que no son válidas como caracteres BMP. Además, dado que UTF-16 tiene dos bytes como unidad básica, se ve afectado por la endianidad . Para compensar, se puede colocar una marca de orden de bytes reservada al comienzo de un flujo de datos que indica endianidad. Por lo tanto, si está leyendo una entrada UTF-16 y no se especifica ningún endianismo, debe verificarlo.

Como puede verse, UTF-8 y UTF-16 no son compatibles entre sí. Entonces, si estás realizando E/S, ¡asegúrate de saber qué codificación estás usando! Para obtener más detalles sobre estas codificaciones, consulte las preguntas frecuentes sobre 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 formato, en el momento en que intente generar caracteres que no sean ASCII, puede encontrarse con algunos problemas. Además, incluso si el tipo de carácter se basa en UTF, eso no significa que las cadenas sean UTF adecuadas. Es posible que permitan secuencias de bytes que sean ilegales. Generalmente, tendrás que usar una biblioteca que admita UTF, como ICU para C, C++ y Java. En cualquier caso, si desea ingresar/salir algo distinto a la codificación predeterminada, primero deberá convertirlo.

Codificaciones recomendadas, predeterminadas y 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, tanto el entorno .NET como el Java se basan en un tipo de carácter UTF-16. De manera confusa (e incorrecta), a menudo se hacen referencias a la "codificación Unicode", que generalmente se refiere a la codificación UTF dominante en un entorno determinado.

Soporte de biblioteca: las bibliotecas que está utilizando admiten algún tipo de codificación. ¿Cuál? ¿Admiten los casos de esquina? Dado que la necesidad es la madre de la invención, las bibliotecas UTF-8 generalmente admitirán correctamente caracteres de 4 bytes, ya que con frecuencia pueden aparecer caracteres de 1, 2 e incluso 3 bytes. Sin embargo, no todas las supuestas bibliotecas UTF-16 admiten pares sustitutos correctamente, ya que ocurren muy raramente.

Contar caracteres: existe combinación de caracteres 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 ñ. Deberían verse idénticos, pero un algoritmo de conteo simple devolverá 2 para el primer ejemplo y 1 para el último. Esto no es necesariamente malo, pero puede que tampoco sea el resultado deseado.

Comparando para determinar la igualdad: A, А y Α se ven iguales, pero son latín, cirílico y griego respectivamente. También tienes casos como C y Ⅽ. Una es una letra y la otra es un número romano. Además, también debemos considerar la combinación de personajes. Para obtener más información, consulte Caracteres duplicados en Unicode .

Pares sustitutos: aparecen con bastante frecuencia en Stack Overflow, por lo que solo proporcionaré algunos enlaces de ejemplo:

  • Obtener la longitud de la cuerda
  • Eliminación de parejas sustitutas
  • Comprobación de palíndromo
DPenner1 avatar Feb 28 '2013 05:02 DPenner1
  • Unicódigo
    • es un conjunto de caracteres utilizados en todo el mundo
  • UTF-8
    • una codificación de caracteres capaz de codificar todos los caracteres posibles (llamados puntos de código) en Unicode.
    • la 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 por " " (tres de 8 bits)
  • UTF-16
    • otra codificación de caracteres
    • la 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)
wengeezhang avatar Jan 06 '2015 07:01 wengeezhang

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

Como siempre se necesita un recurso creíble, pero el informe oficial es enorme, sugiero leer lo siguiente:

  1. El mínimo absoluto que todo desarrollador de software debe saber absoluta y positivamente sobre Unicode y los conjuntos de caracteres (¡sin excusas!) Una introducción de Joel Spolsky, director ejecutivo de Stack Exchange.
  2. ¡Al BMP y más allá! Un tutorial de Eric Muller, entonces director técnico y luego vicepresidente de The Unicode Consortium (las primeras 20 diapositivas y listo)

Una breve explicación:

Las computadoras leen bytes y las personas leen caracteres, por lo que utilizamos estándares de codificación para asignar caracteres a bytes. ASCII fue el primer estándar ampliamente utilizado, pero cubre sólo el latín (siete bits/carácter pueden 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, es decir, 21 bits/caracteres como máximo. Unicode 8.0 actual especifica 120.737 caracteres en total, y eso es todo).

La principal diferencia es que un carácter ASCII puede caber en un byte (ocho bits), pero la mayoría de los caracteres Unicode no. 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 del 0 al 1.114.111 (hexadecimal: 0-10FFFF) denominada 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 la memoria, unidades de 8 bits, unidades de 16 bits, etc. UTF-8 usa de una a cuatro unidades de ocho bits, y UTF-16 usa una o dos unidades de 16 bits, para cubrir todo el Unicode de 21 bits como máximo. Las unidades utilizan prefijos para que se puedan detectar los límites de los caracteres, y más unidades significan más prefijos que ocupan bits. Entonces, aunque UTF-8 usa un byte para la escritura latina, necesita tres bytes para escrituras posteriores dentro de un Plano Multilingüe Básico , mientras que UTF-16 usa dos bytes para todos estos. Y esa es su principal diferencia.
Por último, un esquema de codificación (como UTF-16BE o UTF-16LE) asigna (serializa) una secuencia de unidad de código a una secuencia de bytes.

carácter: π
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 cuatro 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.

Neuron avatar Oct 27 '2015 01:10 Neuron

El artículo Lo que todo programador absolutamente necesita saber sobre codificaciones y juegos de caracteres para trabajar con texto explica todos los detalles.

Escribir en el búfer

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

00000000 11100011 10000001 10000010

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

00000000 00000000 00110000 01000010

Como puedes ver, dependiendo del idioma que uses en tu contenido, esto afectará tu memoria en consecuencia.

Ejemplo: Para este símbolo en particular: la codificación UTF16 es más eficiente ya que tenemos 2 bytes libres para usar en el siguiente símbolo. Pero eso no significa que debas usar UTF16 para el alfabeto japonés.

Lectura del búfer

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

por ejemplo, si decodifica esto: 00000000 11100011 10000001 10000010 en codificación UTF16, terminará sin

Nota: La codificación y Unicode son dos cosas diferentes. Unicode es la (tabla) grande con cada símbolo asignado a un punto de código único. por ejemplo, el símbolo (letra) tiene un (punto de código) : 30 42 (hexadecimal). La codificación, por otro lado, es un algoritmo que convierte símbolos de una manera más apropiada cuando se almacenan en el 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.

Ingrese la descripción de la imagen aquí

InGeek avatar Jan 17 '2017 22:01 InGeek

Originalmente, Unicode estaba destinado a tener una codificación de 16 bits de ancho fijo ( UCS-2 ). Los primeros en adoptar Unicode, como Java y Windows NT, construyeron sus bibliotecas en torno a cadenas de 16 bits.

Posteriormente, el alcance de Unicode se amplió para incluir caracteres históricos, lo que requeriría más de los 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 habían utilizado UCS-2, se introdujo la codificación UTF-16. Utiliza "pares sustitutos" para representar personajes en los planos suplementarios.

Mientras tanto, muchos protocolos de red y software antiguos utilizaban cadenas de 8 bits. UTF-8 se creó para que estos sistemas pudieran admitir Unicode sin tener que utilizar caracteres anchos. Es compatible con versiones anteriores de ASCII de 7 bits.

dan04 avatar Jul 05 '2010 05:07 dan04