Según el artículo de Wikipedia , UTF-8 tiene este formato:
Primer código Último código Bytes Byte 1 Byte 2 Byte 3 Byte 4 punto punto utilizado U + 0000 U + 007F 1 0xxxxxxx U + 0080 U + 07FF 2 110xxxxx 10xxxxxx U + 0800 U + FFFF 3 1110xxxx 10xxxxxx 10xxxxxx U + 10000 U + 1FFFFF 4 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx x significa que este bit se usa para seleccionar el punto de código.
Esto desperdicia dos bits en cada byte de continuación y un bit en el primer byte. ¿Por qué UTF-8 no está codificado como el siguiente?
Primer código Último código Bytes Byte 1 Byte 2 Byte 3 punto punto utilizado U + 0000 U + 007F 1 0xxxxxxx U + 0080 U + 3FFF 2 10xxxxxx xxxxxxxx U + 0800 U + 1FFFFF 3110xxxxx xxxxxxxx xxxxxxxx
Ahorraría un byte cuando el punto de código está fuera del plano multilingüe básico o si el punto de código está dentro del rango [U + 800, U + 3FFF].
¿Por qué UTF-8 no está codificado de una manera más eficiente?
Respuestas:
Esto se hace para que pueda detectar cuándo se encuentra en medio de una secuencia de varios bytes. Cuando observa los datos UTF-8, sabe que si ve
10xxxxxx
, se encuentra en el medio de un carácter multibyte y debe retroceder en la secuencia hasta que vea uno0xxxxxx
u otro11xxxxxx
. Usando su esquema, los bytes 2 o 3 podrían terminar fácilmente con patrones como0xxxxxxx
o11xxxxxx
También tenga en cuenta que cuánto se guarda varía completamente según el tipo de datos de cadena que está codificando. Para la mayoría del texto, incluso el texto asiático, rara vez verá, si alguna vez, caracteres de cuatro bytes con texto normal. Además, las estimaciones ingenuas de las personas sobre cómo se verá el texto a menudo son incorrectas. Tengo texto localizado para UTF-8 que incluye cadenas japonesas, chinas y coreanas, pero en realidad es el ruso el que ocupa más espacio. (Debido a que nuestras cadenas asiáticas a menudo tienen caracteres romanos intercalados para nombres propios, signos de puntuación y demás, y porque la palabra china promedio es de 1-3 caracteres, mientras que la palabra rusa promedio es muchos, muchos más).
fuente
La forma oficial le permite al decodificador saber cuándo está en el medio de la tupla y sabe omitir bytes (o ir hacia atrás) hasta que el byte comience con
0
o11
; Esto evita los valores basura cuando un solo byte se corrompe.fuente
Respuesta corta, su propuesta no diferencia entre el primer byte y los bytes de continuación.
El patrón de bits en el extremo superior del primer byte le indica con cuántos bytes se construye el carácter real. Estos patrones también proporcionan cierto reconocimiento de errores al analizar una cadena. Si está leyendo (aparentemente) el primer byte de un personaje y obtiene 10xxxxxx, entonces sabe que no está sincronizado.
fuente
Lo que no se ha mencionado es que si tiene una secuencia correcta de puntos de código y un puntero que está garantizado para apuntar al primer byte de un punto de código, con UTF-8 puede encontrar fácilmente el puntero al primer byte del punto de código anterior (omita todos los bytes que comienzan con 01xx xxxx). Con su codificación, es imposible sin examinar potencialmente todos los bytes hasta el comienzo de la cadena.
Considere las secuencias de (2n + 2) bytes
y
Si tiene un puntero al primer byte del primer punto de código después de esta secuencia, debe examinar todos los bytes para averiguar si el último punto de código es 0xxxxxxx o (10xxxxxx, 0xxxxxxx).
En realidad, existen esquemas de codificación más eficientes, en los que se puede ir al punto de código anterior en tiempo constante y se pueden corregir los punteros al centro de un punto de código. Permitir los siguientes códigos:
Si uno de los tres bytes anteriores es ≥ 236, entonces es el comienzo de una secuencia de 3 bytes, porque no puede haber dos bytes dentro de una secuencia válida de 3 bytes. De lo contrario, si uno de los dos bytes anteriores es ≥ 128, entonces es el comienzo de una secuencia de dos bytes. De lo contrario, el byte anterior es un solo byte <128.
La búsqueda de una subcadena se vuelve un poco más difícil. Es posible que desee excluir cero bytes para que una cadena solo contenga un byte cero si contiene un punto de código cero.
fuente