2009-10-09 5 views
76

El estándar Unicode tiene suficientes puntos de código que necesita 4 bytes para almacenarlos todos. Eso es lo que hace la codificación UTF-32. Sin embargo, la codificación UTF-8 de alguna manera los exprime en espacios mucho más pequeños mediante el uso de algo llamado "codificación de ancho variable".¿Cómo funciona la codificación de ancho variable UTF-8?

De hecho, se las arregla para representar los primeros 127 caracteres de US-ASCII en un solo byte que se ve exactamente como ASCII real, por lo que puede interpretar mucho texto ascii como si fuera UTF-8 sin hacerle nada . Buen truco. ¿Entonces, cómo funciona?

voy a preguntar y responder a mi propia pregunta aquí porque acabo de hacer un poco de lectura para averiguarlo y pensé que podría salvar a otra persona algún tiempo. Además, tal vez alguien me puede corregir si tengo algo de malo.

+7

Straight Unicode does * not * requiere 32 bits para codificar todos sus puntos de código. Una vez reclamaron muchos posibles puntos de código, pero después de que despegó UTF-8, se limitaron intencionalmente a 21 bits, de modo que UTF-8 nunca excederá los 4 bytes por carácter. Actualmente, Unicode requiere solo 17 bits para contener todos los puntos de código posibles. Sin esta limitación, UTF-8 podría haber ido a 6 bytes por carácter. –

+0

@ Warren: mayormente preciso, pero Unicode es un código de 21 bits (U + 0000 a U + 10FFFF). –

+2

@ Warren: el UTF-8 de 4 bytes podría haber sido compatible con U + 1FFFFF. La restricción a U + 10FFFF se realizó por el bien de UTF-16. – dan04

Respuesta

94

Cada byte comienza con algunas cosas que le indican si se trata de un solo byte de código de punto, un punto de código de varios bytes, o una continuación de un punto de código de varios bytes. De esta manera:

0xxx xxxx A single-byte US-ASCII code (from the first 127 characters) 

Los multi-byte del código de puntos de cada puesta en marcha con algunas cosas que básicamente decir "eh, es necesario leer también el siguiente byte (o dos, o tres) para averiguar lo que soy " Ellos son:

110x xxxx One more byte follows 
1110 xxxx Two more bytes follow 
1111 0xxx Three more bytes follow 

Por último, los bytes que siguen los códigos de inicio de todo este aspecto:

10xx xxxx A continuation of one of the multi-byte characters 

Ya que se puede decir qué tipo de bytes que estás mirando desde los primeros pocos bits, entonces, incluso si algo se destroza en alguna parte, no pierdes toda la secuencia.

+12

Hay más en la historia que eso, porque la codificación debe ser la codificación más corta posible para el carácter, lo que significa que los bytes 0xC0 y 0xC1 no pueden aparecer en UTF-8, por ejemplo; y, de hecho, ninguno puede 0xF5..0xFF. Consulte las preguntas frecuentes de UTF-8 en http://unicode.org/faq/utf_bom.html, o http://www.unicode.org/versions/Unicode5.2.0/ch03.pdf –

+0

¿Por qué no podría usar solo una? char para decir 'next char is continuation'? Si tenemos un carácter de 3 bytes, sería como: '1xxxxxxx 1xxxxxxx 0xxxxxxx', por lo que se desperdiciará menos espacio. – Soaku

+1

@Soaku hace que UTF-8 sea un código llamado "autosincronizador". Esto significa que si debido a errores faltan partes de la secuencia, es posible detectar eso y descartar todo lo que haya quedado distorsionado. Si lee un byte que comienza con 10xx, y no hay ningún byte de "inicio" precedente, puede descartarlo ya que no tiene sentido. Si tenía un sistema como el que describió, y uno de los primeros bytes se pierde, puede terminar con un carácter diferente y válido sin indicación de ningún tipo de error. También facilitará la localización del siguiente carácter válido, así como la corrección de los bytes de "continuación" faltantes. – htmlcoderexe

1

UTF-8 fue otro sistema para almacenar su serie de puntos de código Unicode, esos mágicos números + U, en la memoria utilizando 8 bytes bits. En UTF-8, cada punto de código de 0-127 se almacena en un solo byte . Solo los puntos de código 128 y anteriores se almacenan utilizando 2, 3, de hecho, hasta 6 bytes.

Extracto de The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)

+0

Es un buen artículo, pero parece que Joel está equivocado con respecto a la longitud máxima de la secuencia; la página de Wikipedia muestra solo 1..4 bytes por carácter. – unwind

+4

Como dije antes, cuando UTF-8 se creó por primera vez, Unicode reclamaba hasta 32 bits para los puntos de código, no porque realmente lo necesitaran, solo porque 32 bits es un valor conveniente y ya habían pasado volando el límite anterior de caracteres de 16 bits. Después de que UTF-8 demostró ser popular, eligieron limitar para siempre la cantidad máxima de puntos de código a 2^21, que es el valor más grande que puede codificar con 4 bytes del esquema UTF-8. Todavía hay menos de 2^17 caracteres en Unicode, por lo que podemos más que cuadruplicar el número de caracteres en Unicode con este nuevo esquema. –

+0

Bien, pero no es la explicación que OP me pide. – Nishant

7

RFC3629 - UTF-8, a transformation format of ISO 10646 es la autoridad final aquí y tiene todas las explicaciones.

En resumen, varios bits en cada byte de la secuencia de 1 a 4 bytes codificada en UTF-8 que representa un solo carácter se utilizan para indicar si es un byte final, un byte inicial, y si es así, cómo muchos bytes siguen. Los bits restantes contienen la carga útil.

+1

Ummmm, tonto, pensé que el estándar Unicode era la autoridad final en UTF-8 –

+6

El estándar Unicode define el propio Unicode. No define varios métodos, el de hoy y el futuro, que se pueden usar para codificar textos unicode para una variedad de propósitos (como almacenamiento y transporte). UTF-8 es uno de esos métodos y la referencia anterior es para el documento que lo define. – azheglov

+0

RFC3629, página 3, sección 3. dice "UTF-8 está definido por el estándar Unicode". –

Cuestiones relacionadas