¿Cuántos caracteres puede codificar UTF-8?

Si UTF-8 tiene 8 bits, ¿no significa que solo puede haber un máximo de 256 caracteres diferentes?

Los primeros 128 puntos de código son los mismos que en ASCII. ¿Pero dice que UTF-8 puede admitir hasta un millón de caracteres?

¿Como funciona esto?

UTF-8 no usa un byte todo el tiempo, es de 1 a 4 bytes.

Los primeros 128 caracteres (US-ASCII) necesitan un byte.

Los siguientes 1.920 caracteres necesitan dos bytes para codificar. Esto cubre el rest de casi todos los alfabetos latinos, y también los alfabetos griegos, cirílicos, coptos, armenios, hebreos, árabes, siríacos y tanas, así como la combinación de marcas diacríticas.

Se necesitan tres bytes para los caracteres en el rest del plano multilingüe básico, que contiene prácticamente todos los caracteres de uso común [12] incluyendo la mayoría de los caracteres chinos, japoneses y coreanos [CJK].

Se necesitan cuatro bytes para los caracteres en los otros planos de Unicode, que incluyen caracteres CJK menos comunes, varios guiones históricos, símbolos matemáticos y emoji (símbolos pictográficos).

fuente: Wikipedia

UTF-8 usa 1-4 bytes por carácter: un byte para los caracteres ascii (los primeros 128 valores Unicode son los mismos que los ascii). Pero eso solo requiere 7 bits. Si se establece el bit más alto (“signo”), esto indica el inicio de una secuencia de múltiples bytes; el número de bits altos consecutivos establecido indica el número de bytes, luego un 0, y los bits restantes contribuyen al valor. Para los otros bytes, los dos bits más altos serán 1 y 0 y los 6 bits restantes son para el valor.

Entonces una secuencia de cuatro bytes comenzaría con 11110 … (… = tres bytes para el valor) luego tres bytes con 6 bits cada uno para el valor, produciendo un valor de 21 bits. 2 ^ 21 excede el número de caracteres Unicode, por lo que todo el Unicode se puede express en UTF8.

De acuerdo con esta tabla, * UTF-8 debería ser compatible con:

2 31 = 2,147,483,648 caracteres

Sin embargo, RFC 3629 restringió los valores posibles, por lo que ahora tenemos un límite de 4 bytes , lo que nos da

2 21 = 2,097,152 caracteres

Tenga en cuenta que una buena parte de esos caracteres están “reservados” para uso personalizado, lo que es bastante útil para las fonts de icons.

* La Wikipedia utilizada muestra una tabla con 6 bytes; desde entonces, han actualizado el artículo.

2017-07-11: Corregido para contar dos veces el mismo punto de código codificado con múltiples bytes

2,164,864 “caracteres” pueden ser potencialmente codificados por UTF-8.

Este número es 2 ^ 7 + 2 ^ 11 + 2 ^ 16 + 2 ^ 21 que proviene de la forma en que funciona la encoding:

  • Los caracteres de 1 byte tienen 7 bits para codificar 0xxxxxxx (0x00-0x7F)

  • Los caracteres de 2 bytes tienen 11 bits para codificar 110xxxxx 10xxxxxx (0xC0-0xDF para el primer byte; 0x80-0xBF para el segundo)

  • Los caracteres de 3 bytes tienen 16 bits para la encoding 1110xxxx 10xxxxxx 10xxxxxx (0xE0-0xEF para el primer byte; 0x80-0xBF para los bytes de continuación)

  • Los caracteres de 4 bytes tienen 21 bits para la encoding 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx (0xF0-0xF7 para el primer byte; 0x80-0xBF para los bytes de continuación)

Como puede ver, esto es significativamente más grande que el Unicode actual (1,112,064 caracteres).

Unicode vs UTF-8

Unicode resuelve puntos de código a caracteres. UTF-8 es un mecanismo de almacenamiento para Unicode. Unicode tiene una especificación. UTF-8 tiene una especificación. Ambos tienen diferentes límites. UTF-8 tiene una diferente hacia arriba.

Unicode

Unicode se designa con “aviones”. Cada avión lleva 2 16 puntos de código. Hay 17 aviones en Unicode. Para un total de 17 * 2^16 puntos de código. El primer avión, el avión 0 o el BMP , es especial en el peso de lo que transporta.

En lugar de explicar todos los matices, permítanme citar el artículo anterior en planos.

Los 17 aviones pueden acomodar 1,114,112 puntos de código. De estos, 2,048 son sustitutos, 66 no son caracteres y 137,468 están reservados para uso privado, dejando 974,530 para asignación pública.

UTF-8

Ahora regresemos al artículo vinculado arriba,

El esquema de encoding utilizado por UTF-8 fue diseñado con un límite mucho mayor de 2 31 puntos de código (32,768 planos), y puede codificar 2 21 puntos de código (32 planos) incluso si está limitado a 4 bytes. [3] Dado que Unicode limita los puntos de código a los 17 planos que pueden codificarse con UTF-16, los puntos de código superiores a 0x10FFFF no son válidos en UTF-8 y UTF-32.

Entonces puedes ver que puedes poner cosas en UTF-8 que no son Unicode válidas. ¿Por qué? Porque UTF-8 acomoda puntos de código que Unicode ni siquiera admite.

UTF-8, incluso con una limitación de cuatro bytes, admite 2 21 puntos de código, que es mucho más que 17 * 2^16

UTF-8 es una encoding de longitud variable con un mínimo de 8 bits por carácter.
Los caracteres con puntos de código más altos tomarán hasta 32 bits.

Cita de Wikipedia: “UTF-8 codifica cada uno de los 1,112,064 puntos de código en el conjunto de caracteres Unicode usando de uno a cuatro bytes de 8 bits (denominados” octetos “en el estándar Unicode).”

Algunos enlaces:

Consulte el estándar Unicode e información relacionada, como su entrada de preguntas frecuentes, UTF-8 UTF-16, UTF-32 y BOM . No es tan fácil navegar, pero es información autorizada, y gran parte de lo que podrías leer sobre el UTF-8 en otros lugares es cuestionable.

El “8” en “UTF-8” se refiere a la longitud de unidades de código en bits. Las unidades de código son entidades que se usan para codificar caracteres, no necesariamente como un mapeo simple de uno a uno. UTF-8 usa una cantidad variable de unidades de código para codificar un personaje.

La colección de caracteres que pueden codificarse en UTF-8 es exactamente la misma que para UTF-16 o UTF-32, es decir, todos los caracteres Unicode. Todos codifican todo el espacio de encoding Unicode, que incluso incluye caracteres no asignados y puntos de código no asignados.

Si bien estoy de acuerdo con mpen en los códigos UTF-8 máximos actuales (2,164,864) (enumerados a continuación, no pude comentar sobre los suyos), está desactivado en 2 niveles si elimina las 2 restricciones principales de UTF-8: solo 4 bytes el límite y los códigos 254 y 255 no se pueden usar (solo eliminó el límite de 4 bytes).

El código de inicio 254 sigue la disposición básica de los bits de inicio (indicador de múltiples bits puesto a 1, un recuento de 6 1, y el terminal 0, sin bits de repuesto) que le proporciona 6 bytes adicionales para trabajar (6 10xxxxxx grupos, 2 adicionales 36 códigos).

El código de inicio 255 no sigue exactamente la configuración básica, no hay un terminal 0 pero se usan todos los bits, lo que le da 7 bytes adicionales (indicador de bits múltiples establecido en 1, un recuento de 7 1 y ningún terminal 0 porque se usan todos los bits ; 7 grupos 10xxxxxx, códigos adicionales de 2 ^ 42).

Sumarlos da un conjunto de caracteres presentables máximo final de 4,468,982,745,216. Esto es más que todos los caracteres en uso actual, idiomas antiguos o muertos y cualquier idioma perdido que se crea. Escritura angelical o celestial ¿alguien?

También hay códigos de un solo byte que se pasan por alto / ignorados en el estándar UTF-8 además de 254 y 255: 128-191, y algunos otros. Algunos son utilizados localmente por el teclado, el código de ejemplo 128 es generalmente un espacio de borrar. Los otros códigos de inicio (y los intervalos asociados) no son válidos por uno o más motivos ( https://en.wikipedia.org/wiki/UTF-8#Invalid_byte_sequences ).