¿Cuál es la base de Unicode y por qué la necesidad de UTF-8 o UTF-16? Investigué esto en Google y busqué aquí también, pero no me queda claro.
En VSS al hacer una comparación de archivos, a veces hay 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.
Respuestas:
¿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 eran unos pocos caracteres de control, puntuación, números y letras como los de esta oración. Desafortunadamente, el extraño mundo actual de intercomunicación global y redes sociales no estaba previsto, y no es demasiado inusual ver inglés, العربية, 汉语, עִבְרִית, ελληνικά, y ភាសាខ្មែរ en el mismo documento (espero no romper ninguno navegadores)
Pero por el bien de la discusión, digamos que Joe Average es un desarrollador de software. Insiste en que solo necesitará inglés y, como tal, solo quiere usar 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 el uso de ASCII es posiblemente desconsiderado con 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 incluya 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 de uso común son representables por solo dos bytes, en una región llamada Plano Bilingüe Multilingüe (BMP) . Ahora se necesita una codificación de caracteres para acceder a este conjunto de caracteres, y como pregunta 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?
Vale la pena mencionar ahora que los caracteres que no están en el BMP incluyen scripts antiguos, símbolos matemáticos, símbolos musicales y caracteres chinos / japoneses / coreanos (CJK) más raros .
Si trabajará principalmente con caracteres ASCII, entonces UTF-8 es ciertamente más eficiente en memoria. Sin embargo, si está trabajando principalmente con scripts no europeos, el uso de UTF-8 podría ser hasta 1.5 veces menos eficiente en memoria que UTF-16. Cuando se trata de grandes cantidades de texto, como páginas web grandes o documentos 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 obtener aplicaciones prácticas.
1
evitar el choque con los caracteres ASCII.Como se puede ver, UTF-8 y UTF-16 no son en absoluto compatibles entre sí. Entonces, si está haciendo E / S, ¡asegúrese de saber qué codificación está 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 que no sean ASCII, puede encontrarse con 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 para C, C ++ y Java. En cualquier caso, si desea ingresar / emitir algo que no sea la codificación predeterminada, primero deberá convertirla.
Codificaciones recomendadas / predeterminadas / dominantes: cuando se le da la opción de elegir 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 caracteres UTF-16. Confusamente (e incorrectamente), a menudo se hacen referencias a la "codificación Unicode", que generalmente se refiere a la codificación UTF dominante en un entorno dado.
Soporte de biblioteca: las bibliotecas que está utilizando admiten algún tipo de codificación. ¿Cúal? ¿Apoyan los casos de esquina? Dado que la necesidad es la madre de la invención, las bibliotecas UTF-8 generalmente admitirán 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) forma ñ, pero el punto de código U + 00F1 forma ñ. Deben verse idénticos, pero un algoritmo de conteo simple devolverá 2 para el primer ejemplo, 1 para el último. Esto no es necesariamente incorrecto, pero tampoco puede ser el resultado deseado.
Comparando para igualdad: A, А y Α se ven iguales, pero son latinos, cirílicos y griegos respectivamente. También tiene casos como C y Ⅽ, uno es una letra y el otro un número romano. Además, también tenemos los caracteres combinados a tener en cuenta. Para más información ver Caracteres duplicados en Unicode .
Pares sustitutos: estos aparecen con bastante frecuencia en SO, por lo que solo proporcionaré algunos enlaces de ejemplo:
¿Otros?:
fuente
fuente
Debido a que siempre se necesita un recurso creíble, pero el informe oficial es masivo, sugiero leer lo siguiente:
Una breve explicación:
Las computadoras leen bytes y las personas leen caracteres, entonces usamos estándares de codificación para asignar caracteres a bytes. ASCII fue el primer estándar ampliamente utilizado, pero cubre solo 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 un máximo de 21 bits / carácter. 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 (8 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 personaje tiene una posición enumerada de 0 a 1,114,111 (hexadecimal: 0-10FFFF) llamado punto de código .
Un formulario de codificación asigna un punto de código a una secuencia de unidad de código. Una unidad de código es la forma en que desea que los caracteres se organicen en la memoria, unidades de 8 bits, unidades de 16 bits, etc. UTF-8 usa 1 a 4 unidades de 8 bits, y UTF-16 usa 1 o 2 unidades de 16 bits, para cubrir todo el Unicode de 21 bits como máximo. Las unidades usan prefijos para que los límites de los caracteres se puedan detectar, 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 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) asigna (serializa) una secuencia de unidad de código a una secuencia de bytes.
carácter:
punto de código π :
formas de codificación U + 03C0 (unidades de código):
UTF-8: CF 80
UTF-16:
esquemas de codificación 03C0 (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 planos en Wikipedia para tener una idea del diseño del juego de caracteres.
fuente
Originalmente, Unicode estaba destinado a tener una codificación de ancho fijo de 16 bits (UCS-2). Los primeros usuarios de Unicode, como Java y Windows NT, construyeron sus bibliotecas en torno a cadenas de 16 bits.
Más tarde, 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 representaran en plataformas que habían usado UCS-2, se introdujo la codificación UTF-16. Utiliza "pares sustitutos" para representar personajes en los planos suplementarios.
Mientras tanto, una gran cantidad de software y protocolos de red más antiguos usaban cadenas de 8 bits. UTF-8 fue creado para que estos sistemas pudieran soportar Unicode sin tener que usar caracteres anchos. Es compatible con versiones anteriores de ASCII de 7 bits.
fuente
Este artículo explica todos los detalles http://kunststube.net/encoding/
ESCRIBIR AL BUFFER
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 puede ver, dependiendo del idioma que usaría en su contenido, esto afectará su memoria en consecuencia.
Por ejemplo, para este símbolo en particular: la
あ
codificación UTF16 es más eficiente ya que tenemos 2 bytes de repuesto para usar para el siguiente símbolo. Pero eso no significa que deba usar UTF16 para el alfabeto japonés.LEYENDO DEL BUFFER
Ahora, si desea leer los bytes anteriores, debe saber en qué codificación se escribió y decodificar de nuevo 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 gran (tabla) 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 los símbolos de una manera más apropiada, cuando se almacena en el hardware.fuente
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 que permite diferentes codificaciones posibles utilizando el mismo conjunto de puntos de código.
UTF-8 y UTF-16 son dos de esas codificaciones. Toman puntos de código como entrada y los codifica usando una fórmula bien definida para producir la cadena codificada.
Elegir una codificación particular depende de sus requisitos. Las diferentes codificaciones tienen diferentes requisitos de memoria y, dependiendo de los caracteres con los que se tratará, debe elegir la codificación que utiliza la menor cantidad de secuencias de bytes para codificar esos caracteres.
Para obtener detalles más detallados sobre Unicode, UTF-8 y UTF-16, puede consultar este artículo,
Lo que todo programador debe saber sobre Unicode
fuente
¿Por qué unicode? Porque ASCII tiene solo 127 caracteres. Los de 128 a 255 difieren en los diferentes países, por eso hay páginas de códigos. Entonces dijeron que tengamos hasta 1114111 caracteres. Entonces, ¿cómo se almacena el punto de código más alto? Deberá almacenarlo con 21 bits, por lo que usará un DWORD que tenga 32 bits con 11 bits desperdiciados. Entonces, si usa 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 una secuencia de WORD, y una WORD tiene 16 bits, entonces, ¿cómo puede encajar el punto de código más alto 1114111 en una WORD? ¡No puede! Así que pusieron todo lo superior a 65535 en un DWORD que llaman un par sustituto. Tal par sustituto son dos PALABRAS y se pueden detectar observando los primeros 6 bits. Entonces, ¿qué pasa con utf-8? Es una matriz de bytes o una secuencia de bytes, pero ¿cómo puede encajar el punto de código más alto 1114111 en un byte? ¡No puede! Bien, entonces pusieron también un DWORD ¿verdad? O posiblemente una PALABRA, ¿verdad? ¡Casi cierto! Inventaron 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 solo byte. 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 "startbytes" pertenecen al punto de código. Ahora, dependiendo de la secuencia, deben seguir los siguientes bytes. Un siguiente byte 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 byte de inicio y los siguientes byte / sy obtendrá el punto de código. Esa es toda la magia de utf-8.
fuente
ASCII: el software asigna solo un byte de 8 bits en la memoria para un carácter dado. Funciona bien para caracteres en inglés y adoptados (palabras de préstamo como fachada) ya que sus valores decimales correspondientes caen por debajo de 128 en el valor decimal. Programa de ejemplo C.
UTF-8: el software asigna de 1 a 4 bytes de 8 bits variables para un carácter dado. ¿Qué significa aquí por variable? Digamos que está enviando el carácter 'A' a través de sus páginas HTML en el navegador (HTML es UTF-8), el valor decimal correspondiente de A es 65, cuando lo convierte en decimal se convierte en 01000010. Esto requiere solo 1 bytes , 1 byte de memoria se asigna incluso para caracteres ingleses especiales adoptados como 'ç' en una palabra de fachada. Sin embargo, cuando desea almacenar caracteres europeos, requiere 2 bytes, por lo que necesita UTF-8. Sin embargo, cuando elige caracteres asiáticos, necesita un mínimo de 2 bytes y un máximo de 4 bytes. Del mismo modo, los Emoji requieren de 3 a 4 bytes. UTF-8 resolverá todas sus necesidades.
UTF-16 asignará un mínimo de 2 bytes y un máximo de 4 bytes por carácter, no asignará 1 o 3 bytes. Cada carácter está representado en 16 bits o 32 bits.
Entonces, ¿por qué existe UTF-16? Originalmente, Unicode era de 16 bits, no de 8 bits. Java adoptó la versión original de UTF-16.
En pocas palabras, no necesita UTF-16 en ninguna parte a menos que ya haya sido adoptado por el idioma o la plataforma en la que está trabajando.
El programa Java invocado por los navegadores web usa UTF-16 pero el navegador web envía caracteres usando UTF-8.
fuente
UTF son las siglas de Unicode Transformation Format. Básicamente, en el mundo actual hay scripts escritos en cientos de otros idiomas, formatos que no están 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.
fuente