unicode - UTF-8, UTF-16 y UTF-32
utf-64 (12)
UTF-8
- no tiene concepto de orden de bytes
- Utiliza entre 1 y 4 bytes por carácter.
- ASCII es un subconjunto compatible de codificación
- completamente auto-sincronizante, por ejemplo, un byte descartado desde cualquier lugar en un flujo corromperá a lo sumo un solo carácter
- prácticamente todos los idiomas europeos están codificados en dos bytes o menos por carácter
UTF-16
- debe analizarse con un orden de bytes conocido o leer una marca de orden de bytes (BOM)
- utiliza 2 o 4 bytes por carácter
UTF-32
- cada caracter es de 4 bytes
- debe analizarse con un orden de bytes conocido o leer una marca de orden de bytes (BOM)
UTF-8 será el más eficiente en espacio a menos que la mayoría de los personajes sean del espacio de caracteres CJK (chino, japonés y coreano).
UTF-32 es mejor para el acceso aleatorio mediante el desplazamiento de caracteres en una matriz de bytes.
¿Cuáles son las diferencias entre UTF-8, UTF-16 y UTF-32?
Entiendo que todos almacenarán Unicode, y que cada uno usa un número diferente de bytes para representar un carácter. ¿Hay una ventaja de elegir uno sobre el otro?
Como se mencionó, la diferencia es principalmente el tamaño de las variables subyacentes, que en cada caso se hacen más grandes para permitir que se representen más caracteres.
Sin embargo, las fuentes, la codificación y las cosas son muy complicadas (¿innecesariamente?), Por lo que se necesita un enlace grande para completar con más detalle:
http://www.cs.tut.fi/~jkorpela/chars.html#ascii
No espere entenderlo todo, pero si no quiere tener problemas más adelante, vale la pena aprender lo más que pueda, tan pronto como pueda (o simplemente conseguir que alguien más lo resuelva por usted).
Pablo.
Dependiendo de su entorno de desarrollo, es posible que ni siquiera tenga la opción de codificar internamente el tipo de datos de su cadena.
Pero para almacenar e intercambiar datos, siempre usaría UTF-8, si tiene la opción. Si tiene la mayoría de los datos ASCII, esto le dará la menor cantidad de datos para transferir, mientras que aún podrá codificar todo. La optimización para el mínimo de E / S es la manera de ir en las máquinas modernas.
En UTF-32 todos los caracteres están codificados con 32 bits. La ventaja es que puede calcular fácilmente la longitud de la cadena. La desventaja es que por cada carácter ASCII se desperdician tres bytes adicionales.
En UTF-8, los caracteres tienen longitud variable, los caracteres ASCII se codifican en un byte (ocho bits), la mayoría de los caracteres especiales occidentales se codifican en dos bytes o tres bytes (por ejemplo, € es tres bytes), y los caracteres más exóticos pueden ocupar a cuatro bytes. La clara desventaja es que a priori no se puede calcular la longitud de la cadena. Pero se necesita mucho menos bytes para codificar el texto del alfabeto latino (inglés), en comparación con UTF-32.
UTF-16 también es de longitud variable. Los caracteres se codifican en dos bytes o cuatro bytes. Realmente no veo el punto. Tiene la desventaja de ser de longitud variable, pero no tiene la ventaja de ahorrar tanto espacio como UTF-8.
De esos tres, claramente UTF-8 es el más extendido.
En breve:
- UTF-8: codificación de ancho variable, compatible con versiones anteriores con ASCII. Los caracteres ASCII (U + 0000 a U + 007F) toman 1 byte, los puntos de código U + 0080 a U + 07FF toman 2 bytes, los puntos de código U + 0800 a U + FFFF toman 3 bytes, los puntos de código U + 10000 a U + 10FFFF tomar 4 bytes. Bueno para texto en inglés, no tan bueno para texto asiático.
- UTF-16: Codificación de ancho variable. Los puntos de código U + 0000 a U + FFFF toman 2 bytes, los puntos de código U + 10000 a U + 10FFFF toman 4 bytes. Malo para el texto en inglés, bueno para el texto asiático.
- UTF-32: Codificación de ancho fijo. Todos los puntos de código toman cuatro bytes. Un enorme cerdo de memoria, pero rápido de operar. Raramente usado.
En mucho tiempo: consulte Wikipedia: UTF-8 , UTF-16 y UTF-32 .
En resumen, la única razón para usar UTF-16 o UTF-32 es para admitir scripts antiguos y no ingleses, respectivamente.
Me preguntaba por qué alguien elegiría tener una codificación que no fuera UTF-8 cuando obviamente es más eficiente para propósitos de programación / web.
Un error común: el número con sufijo NO es una indicación de su capacidad. Todos soportan el Unicode completo, solo que UTF-8 puede manejar ASCII con un solo byte, por lo que es MÁS eficiente / menos dañable para la CPU y en Internet.
Algunas buenas lecturas: http://www.personal.psu.edu/ejp10/blogs/gotunicode/2007/10/which_utf_do_i_use.html y http://utf8everywhere.org
Hice algunas pruebas para comparar el rendimiento de la base de datos entre UTF-8 y UTF-16 en MySQL.
Velocidades de actualización
UTF-8
UTF-16
Velocidades de inserción
Velocidades de borrado
Intenté dar una explicación simple en mi blogpost .
UTF-32
Requiere 32 bits (4 bytes) para codificar cualquier carácter. Por ejemplo, para representar el punto de código del carácter "A" utilizando este esquema, deberá escribir 65 en un número binario de 32 bits:
00000000 00000000 00000000 01000001 (Big Endian)
Si observa detenidamente, observará que los siete bits más a la derecha son en realidad los mismos bits cuando se utiliza el esquema ASCII. Pero como UTF-32 es un esquema de ancho fijo , debemos adjuntar tres bytes adicionales. Lo que significa que si tenemos dos archivos que solo contienen el carácter "A", uno está codificado en ASCII y el otro está codificado en UTF-32, su tamaño será de 1 byte y 4 bytes de manera correspondiente.
UTF-16
Mucha gente piensa que, como UTF-32 usa un ancho fijo de 32 bits para representar un punto de código, UTF-16 tiene un ancho fijo de 16 bits. ¡INCORRECTO!
En UTF-16, el punto de código puede representarse en 16 bits, O 32 bits. Así que este esquema es el sistema de codificación de longitud variable. ¿Cuál es la ventaja sobre el UTF-32? Al menos para ASCII, el tamaño de los archivos no será 4 veces el original (pero aún dos veces), por lo que aún no somos compatibles con ASCII con versiones anteriores.
Como los 7 bits son suficientes para representar el carácter "A", ahora podemos usar 2 bytes en lugar de 4 como el UTF-32. Se verá como
00000000 01000001
UTF-8
Lo has adivinado. En UTF-8, el punto de código puede representarse con 32, 16, 24 u 8 bits, y como sistema UTF-16, este también es un sistema de codificación de longitud variable.
Finalmente, podemos representar "A" de la misma manera que lo representamos utilizando el sistema de codificación ASCII:
01001101
Un pequeño ejemplo donde UTF-16 es realmente mejor que UTF-8:
Considere la letra china "語" - su codificación UTF-8 es:
11101000 10101010 10011110
Si bien su codificación UTF-16 es más corta:
10001010 10011110
Para entender la representación y cómo se interpreta, visite la publicación original.
UTF-8 tiene una ventaja en el caso en que los caracteres ASCII representan la mayoría de los caracteres en un bloque de texto, porque UTF-8 codifica todos los caracteres en 8 bits (como ASCII). También es ventajoso porque un archivo UTF-8 que contiene solo caracteres ASCII tiene la misma codificación que un archivo ASCII.
UTF-16 es mejor donde ASCII no es predominante, ya que utiliza 2 bytes por carácter, principalmente. UTF-8 comenzará a usar 3 o más bytes para los caracteres de orden superior donde UTF-16 permanece en solo 2 bytes para la mayoría de los caracteres.
UTF-32 cubrirá todos los caracteres posibles en 4 bytes. Esto lo hace bastante hinchado. No puedo pensar en ninguna ventaja de usarlo.
Unicode define un único conjunto de caracteres enormes, asignando un valor entero único a cada símbolo gráfico (que es una simplificación importante, y en realidad no es cierto, pero es lo suficientemente cerca para los propósitos de esta pregunta). UTF-8/16/32 son simplemente formas diferentes de codificar esto.
En resumen, UTF-32 usa valores de 32 bits para cada carácter. Eso les permite usar un código de ancho fijo para cada personaje.
UTF-16 usa 16 bits por defecto, pero eso solo le da 65k caracteres posibles, lo que no es suficiente para el conjunto completo de Unicode. Así que algunos caracteres usan pares de valores de 16 bits.
Y UTF-8 usa valores de 8 bits por defecto, lo que significa que los primeros 127 valores son caracteres de un solo byte de ancho fijo (el bit más significativo se usa para indicar que este es el comienzo de una secuencia de múltiples bytes, dejando 7 bits para el valor del carácter real). Todos los demás caracteres se codifican como secuencias de hasta 4 bytes (si la memoria sirve).
Y eso nos lleva a las ventajas. Cualquier carácter ASCII es directamente compatible con UTF-8, por lo que para actualizar aplicaciones heredadas, UTF-8 es una opción común y obvia. En casi todos los casos, también utilizará la menor memoria. Por otro lado, no puedes garantizar el ancho de un personaje. Puede tener 1, 2, 3 o 4 caracteres de ancho, lo que dificulta la manipulación de las cuerdas.
UTF-32 es opuesto, usa la mayor cantidad de memoria (cada carácter tiene un ancho fijo de 4 bytes), pero, por otro lado, sabes que cada carácter tiene esta longitud precisa, por lo que la manipulación de cadenas se vuelve mucho más sencilla. Puede calcular el número de caracteres en una cadena simplemente a partir de la longitud en bytes de la cadena. No puedes hacer eso con UTF-8.
UTF-16 es un compromiso. Permite que la mayoría de los caracteres se ajusten a un valor de 16 bits de ancho fijo. Entonces, mientras no tenga símbolos chinos, notas musicales o algunos otros, puede asumir que cada carácter tiene 16 bits de ancho. Utiliza menos memoria que UTF-32. Pero es de alguna manera "lo peor de ambos mundos". Casi siempre usa más memoria que UTF-8, y aún así no evita el problema que afecta a UTF-8 (caracteres de longitud variable).
Finalmente, a menudo es útil ir solo con lo que la plataforma admite. Windows usa UTF-16 internamente, así que en Windows, esa es la opción obvia.
Linux varía un poco, pero generalmente usan UTF-8 para todo lo que es compatible con Unicode.
Respuesta corta: las tres codificaciones pueden codificar el mismo conjunto de caracteres, pero representan cada carácter como diferentes secuencias de bytes.
Unicode es un estándar y, sobre UTF-x , puede pensar como una implementación técnica para algunos propósitos prácticos:
- UTF-8 : " tamaño optimizado ": se adapta mejor a los datos basados en caracteres latinos (o ASCII), toma solo 1 byte por carácter, pero el tamaño aumenta según la variedad de símbolos (y en el peor de los casos puede aumentar hasta 6 bytes por carácter)
- UTF-16 - " balance ": toma un mínimo de 2 bytes por carácter, lo que es suficiente para el conjunto existente de los idiomas principales con un tamaño fijo para facilitar el manejo de los caracteres (pero el tamaño sigue siendo variable y puede crecer hasta 4 bytes por carácter )
- UTF-32 - " rendimiento ": permite el uso de algoritmos simples como resultado de caracteres de tamaño fijo (4 bytes) pero con desventaja de memoria
UTF-8 es variable de 1 a 4 bytes.
UTF-16 es variable 2 o 4 bytes.
UTF-32 es fijo de 4 bytes.