Estándar | Estándar Unicode |
---|---|
Clasificación | Formato de transformación Unicode, ASCII extendido, codificación de ancho variable |
Se extiende | US-ASCII |
Transforma / Codifica | ISO 10646 ( Unicode ) |
Precedido por | UTF-1 |
|
UTF-8 es una codificación de caracteres de ancho variable que se utiliza para la comunicación electrónica. Definido por el estándar Unicode, el nombre se deriva del formato de transformación Unicode (o juego de caracteres codificados universal): 8 bits.
UTF-8 es capaz de codificar todos los 1,112,064 puntos de código de caracteres válidos en Unicode usando de una a cuatro unidades de código de un byte (8 bits). Los puntos de código con valores numéricos más bajos, que tienden a ocurrir con más frecuencia, se codifican utilizando menos bytes. Fue diseñado para ser compatible con versiones anteriores de ASCII : los primeros 128 caracteres de Unicode, que corresponden uno a uno con ASCII, se codifican utilizando un solo byte con el mismo valor binario que ASCII, de modo que el texto ASCII válido es UTF-8 válido -codificado Unicode también. Dado que los bytes ASCII no ocurren cuando se codifican puntos de código no ASCII en UTF-8, UTF-8 es seguro de usar en la mayoría de los lenguajes de programación y documentos que interpretan ciertos caracteres ASCII de una manera especial, como /
( barra ) en nombres de archivo, \
( barra invertida ) en secuencias de escape y %
en printf.
UTF-8 se diseñó como una alternativa superior a UTF-1, una codificación de ancho variable propuesta con compatibilidad parcial con ASCII que carecía de algunas características, incluida la sincronización automática y el manejo de caracteres totalmente compatible con ASCII, como barras. Ken Thompson y Rob Pike produjeron la primera implementación para el sistema operativo Plan 9 en septiembre de 1992. Esto llevó a su adopción por X / Open como su especificación para FSS-UTF, que se presentaría oficialmente por primera vez en USENIX en enero de 1993 y posteriormente se adoptó por el Grupo de trabajo de ingeniería de Internet (IETF) en RFC 2277 ( BCP 18) para el trabajo futuro de estándares de Internet, reemplazando los conjuntos de caracteres de un solo byte como Latin-1 en RFC más antiguos.
UTF-8 es, con mucho, la codificación más común para la World Wide Web, ya que representa más del 97% de todas las páginas web y hasta el 100% para algunos idiomas, a partir de 2021.
El código oficial de la Autoridad de Números Asignados de Internet (IANA) para la codificación es "UTF-8". Todas las letras están en mayúsculas y el nombre está dividido con guión. Esta ortografía se utiliza en todos los documentos del Consorcio Unicode relacionados con la codificación.
Alternativamente, el nombre " utf-8 " puede ser utilizado por todos los estándares que cumplen con la lista de IANA (que incluyen encabezados CSS, HTML, XML y HTTP ), ya que la declaración no distingue entre mayúsculas y minúsculas.
Otras variantes, como las que omiten el guión o lo reemplazan por un espacio, es decir, " utf8 " o " UTF 8 ", no son aceptadas como correctas por las normas vigentes. A pesar de esto, la mayoría de los navegadores web pueden comprenderlos, por lo que los estándares destinados a describir la práctica existente (como HTML5) pueden requerir su reconocimiento de manera efectiva.
Extraoficialmente, UTF-8-BOM y UTF-8-NOBOM a veces se usan para archivos de texto que contienen o no contienen una marca de orden de bytes (BOM), respectivamente. En Japón, especialmente, la codificación UTF-8 sin una lista de materiales a veces se denomina " UTF-8N ".
Windows XP y posteriores, incluidas todas las versiones compatibles de Windows, tienen la página de códigos 65001, como sinónimo de UTF-8 (ya que el soporte de Windows 7 para UTF-8 es mejor), y Microsoft tiene un script para Windows 10, para habilitarlo de forma predeterminada para su programa Microsoft Notepad.
En PCL, UTF-8 se denomina ID de símbolo "18N" (PCL admite 183 codificaciones de caracteres, llamados Conjuntos de símbolos, que potencialmente podrían reducirse a uno, 18N, que es UTF-8).
Desde la restricción del espacio de código Unicode a valores de 21 bits en 2003, UTF-8 se define para codificar puntos de código en uno a cuatro bytes, dependiendo del número de bits significativos en el valor numérico del punto de código. La siguiente tabla muestra la estructura de la codificación. Los caracteres x se reemplazan por los bits del punto de código.
Primer punto de código | Último punto de código | Byte 1 | Byte 2 | Byte 3 | Byte 4 |
---|---|---|---|---|---|
U + 0000 | U + 007F | 0xxxxxxx | |||
U + 0080 | U + 07FF | 110xxxxx | 10xxxxxx | ||
U + 0800 | U + FFFF | 1110xxxx | 10xxxxxx | 10xxxxxx | |
U + 10000 | U + 10FFFF | 11110xxx | 10xxxxxx | 10xxxxxx | 10xxxxxx |
Los primeros 128 caracteres (US-ASCII) necesitan un byte. Los siguientes 1.920 caracteres necesitan dos bytes para codificarse, lo que cubre el resto de casi todos los alfabetos de escritura latina, y también las extensiones IPA, los alfabetos griego, cirílico, copto, armenio, hebreo, árabe, siríaco, thaana y N'Ko. como Signos diacríticos para combinar. Se necesitan tres bytes para los caracteres del resto del plano multilingüe básico, que contiene prácticamente todos los caracteres de uso común, incluida la mayoría de los caracteres chinos, japoneses y coreanos. Se necesitan cuatro bytes para caracteres en los otros planos de Unicode, que incluyen caracteres CJK menos comunes, varios scripts históricos, símbolos matemáticos y emoji (símbolos pictográficos).
Un "carácter" en realidad puede tomar más de 4 bytes, por ejemplo, un carácter de bandera emoji toma 8 bytes ya que está "construido a partir de un par de valores escalares Unicode".
Considere la codificación del signo euro, €:
Los tres bytes 1110 0010 10 000010 10 101100 pueden escribirse de forma más concisa en hexadecimal, como E2 82 AC.
La siguiente tabla resume esta conversión, así como otras con diferentes longitudes en UTF-8. Los colores indican cómo se distribuyen los bits del punto de código entre los bytes UTF-8. Los bits adicionales agregados por el proceso de codificación UTF-8 se muestran en negro.
Personaje | Punto de código binario | UTF-8 binario | UTF-8 hexagonal | |
---|---|---|---|---|
PS | U + 0024 | 010 0100 | 0 0100100 | 24 |
¢ | U + 00A2 | 000 10 10 0010 | 110 00010 10 100010 | C2 A2 |
ह | U + 0939 | 0000 1001 00 11 1001 | 1 110 0.000 10 100,100 10 111.001 mil | E0 A4 B9 |
€ | U + 20AC | 0010 0000 10 10 1100 | 1110 0010 10 000010 10 101100 | E2 82 AC |
한 | U + D55C | 1101 0101 01 01 1100 | 1,11 mil 1101 10 010101 10 011,1 mil | ED 95 9C |
𐍈 | U + 10348 | 0 00 01 0000 0011 01 00 1000 | 11110 000 10 010000 10 001101 10 001000 | F0 90 8D 88 |
El uso de UTF-8 de seis bits por byte para representar los caracteres reales que se codifican, significa que la notación octal (que usa grupos de 3 bits) puede ayudar en la comparación de secuencias UTF-8 entre sí y en la conversión manual.
Primer punto de código | Último punto de código | Punto de código | Byte 1 | Byte 2 | Byte 3 | Byte 4 |
---|---|---|---|---|---|---|
000 | 177 | xxx | xxx | |||
0200 | 3777 | xxyy | 3xx | 2aa | ||
04000 | 77777 | xyyzz | 34x | 2aa | 2zz | |
100000 | 177777 | 1xyyzz | 35x | 2aa | 2zz | |
0200000 | 4177777 | xyyzzww | 36 veces | 2aa | 2zz | 2ww |
Con la notación octal, los dígitos octales arbitrarios, marcados con x, y, zow en la tabla, permanecerán sin cambios al convertir hacia o desde UTF-8.
La siguiente tabla resume el uso de unidades de código UTF-8 ( bytes u octetos individuales) en un formato de página de códigos. La mitad superior ( 0_ a 7_) es para bytes usados solo en códigos de un solo byte, por lo que parece una página de códigos normal; la mitad inferior es para los bytes de continuación ( 8_ a B_) y los bytes iniciales ( C_ a F_), y se explica con más detalle en la leyenda siguiente.
_0 | _1 | _2 | _3 | _4 | _5 | _6 | _7 | _8 | _9 | _A | _B | _C | _D | _MI | _F | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
(1 byte) 0_ | NUL 0000 | SOH 0001 | STX 0002 | ETX 0003 | EOT 0004 | ENQ 0005 | ACK 0006 | BEL 0007 | BS 0008 | HT 0009 | LF 000A | VT 000B | FF 000C | CR 000D | SO 000E | SI 000F |
(1) 1_ | DLE 0010 | DC1 0011 | DC2 0012 | DC3 0013 | DC4 0014 | NAK 0015 | SYN 0016 | ETB 0017 | PUEDE 0018 | EM 0019 | SUB 001A | ESC 001B | FS 001C | GS 001D | RS 001E | US 001F |
(1) 2_ | SP 0020 | ! 0021 | " 0022 | # 0023 | $ 0024 | % 0025 | y 0026 | « 0027 | ( 0028 | ) 0029 | * 002A | + 002B | , 002C | - 002D | . 002E | / 002F |
(1) 3_ | 0 0030 | 1 0031 | 2 0032 | 3 0033 | 4 0034 | 5 0035 | 6 0036 | 7 0037 | 8 0038 | 9 0039 | : 003A | ; 003B | lt; 003C | = 003D | gt; 003E | ? 003F |
(1) 4_ | @ 0040 | A 0041 | B 0042 | C 0043 | D 0044 | E 0045 | F 0046 | G 0047 | H 0048 | Yo 0049 | J 004A | K 004B | L 004C | M 004D | N 004E | O 004F |
(1) 5_ | P 0050 | Q 0051 | R 0052 | S 0053 | T 0054 | U 0055 | V 0056 | W 0057 | X 0058 | Y 0059 | Z 005A | [ 005B | \ 005C | ] 005D | ^ 005E | _ 005F |
(1) 6_ | ` 0060 | un 0061 | b 0062 | c 0063 | d 0064 | e 0065 | f 0066 | g 0067 | h 0068 | yo 0069 | j 006A | k 006B | l 006C | m 006D | n 006E | o 006F |
(1) 7_ | p 0070 | q 0071 | r 0072 | s 0073 | t 0074 | u 0075 | v 0076 | w 0077 | x 0078 | y 0079 | z 007A | { 007B | | 007C | } 007D | ~ 007E | DEL 007F |
8_ | • +00 | • +01 | • +02 | • 03 | • +04 | • +05 | • +06 | • +07 | • +08 | • +09 | • + 0A | • + 0B | • + 0C | • + 0D | • + 0E | • + 0F |
9_ | • +10 | • +11 | • +12 | • 13 | • +14 | • +15 | • +16 | • +17 | • 18 | • +19 | • + 1A | • + 1B | • + 1C | • + 1D | • + 1E | • + 1F |
A_ | • +20 | • +21 | • +22 | • +23 | • +24 | • +25 | • +26 | • +27 | • +28 | • +29 | • + 2A | • + 2B | • + 2C | • + 2D | • + 2E | • + 2F |
B_ | • +30 | • +31 | • +32 | • +33 | • 34 | • +35 | • +36 | • +37 | • +38 | • +39 | • + 3A | • + 3B | • + 3C | • + 3D | • + 3E | • + 3F |
(2) C_ | 2 0000 | 2 0040 | América 0080 | Latina 00C0 | América 0100 | América 0140 | Latina 0180 | Latina 01C0 | Latina 0200 | IPA 0240 | IPA 0280 | IPA 02C0 | acentos 0300 | acentos … 0340 | Griega 0380 | Griego 03C0 |
(2) D_ | Cirilo 0400 | Cirilo 0440 | Cirilo 0480 | Cirilo 04C0 | Cirilo … 0500 | Armeni 0540 | hebreo 0580 | Hebreo 05C0 | Árabe 0600 | Árabe 0640 | Árabe 0680 | Árabe 06C0 | Siríaco 0700 | Árabe 0740 | Thaana 0780 | NKo 07C0 |
(3) E_ | Indic 0800 | Misc. 1000 | Símbolo 2000 | Kana … 3000 | CJK 4000 | CJK 5000 | CJK 6000 | CJK 7000 | CJK 8000 | CJK 9000 | Asiático A000 | Hangul B000 | Hangul C000 | Hangul D000 | PUA E000 | PUA. .. F000 |
(4) F_ | SMP… 10000 | 40000 | 80000 | SSP... C0000 | SPUA-B 100000 | 4 140000 | 4 180000 | 4 1C0000 | 5 200,000 | 5 1000000 | 5 2000000 | 5 3000000 | 6 4000000 | 6 40000000 |
Las celdas azules son secuencias de 7 bits (de un solo byte). No deben ir seguidos de un byte de continuación.
Las celdas naranjas con un punto grande son un byte de continuación. El número hexadecimal que se muestra después del símbolo + es el valor de los 6 bits que agregan. Este carácter nunca aparece como el primer byte de una secuencia de varios bytes.
Las celdas blancas son los bytes iniciales de una secuencia de varios bytes, la longitud que se muestra en el borde izquierdo de la fila. El texto muestra los bloques Unicode codificados por secuencias que comienzan con este byte, y el punto de código hexadecimal que se muestra en la celda es el valor de carácter más bajo codificado usando ese byte inicial.
Los glóbulos rojos nunca deben aparecer en una secuencia UTF-8 válida. Los dos primeros glóbulos rojos ( C0 y C1) solo se pueden utilizar para una codificación de 2 bytes de un carácter ASCII de 7 bits que debe codificarse en 1 byte; como se describe a continuación, tales secuencias "demasiado largas" no están permitidas. Para entender por qué es así, considere el carácter 128, hexadecimal 80, binario 1000 0000. Para codificarlo como 2 caracteres, los seis bits inferiores se almacenan en el segundo carácter como 128 en sí mismo 10 000000, pero los dos bits superiores se almacenan en el primer carácter como 110 00010, lo que hace que el primer carácter mínimo sea C2. Los glóbulos rojos en la fila F_ ( F5 a FD) indican bytes iniciales de secuencias de 4 bytes o más que no pueden ser válidas porque codificarían puntos de código mayores que el límite U + 10FFFF de Unicode (un límite derivado del punto de código máximo codificable en UTF-16 ). FE y FF no coinciden con ningún patrón de caracteres permitido y, por lo tanto, no son bytes de inicio válidos.
Las celdas rosadas son los bytes iniciales de una secuencia de varios bytes, de los cuales algunas, pero no todas, las posibles secuencias de continuación son válidas. E0 y F0 podrían iniciar codificaciones demasiado largas, en este caso se muestra el punto de código no demasiado largo más bajo. F4 puede iniciar puntos de código superiores a U + 10FFFF que no son válidos. ED puede iniciar la codificación de un punto de código en el rango U + D800 – U + DFFF; estos no son válidos ya que están reservados para mitades sustitutas UTF-16.
En principio, sería posible aumentar el número de bytes en una codificación rellenando el punto de código con ceros a la izquierda. Para codificar el signo euro € del ejemplo anterior en cuatro bytes en lugar de tres, podría rellenarse con ceros a la izquierda hasta que tuviese 21 bits de longitud - 000 000010 000010 101100, y codificado como 11110 000 10 000010 10 000010 10 101100 (o F0 82 82 AC en hexadecimal). Esto se denomina codificación demasiado larga.
El estándar especifica que la codificación correcta de un punto de código utiliza solo el número mínimo de bytes necesarios para contener los bits significativos del punto de código. Las codificaciones más largas se denominan demasiado largas y no son representaciones UTF-8 válidas del punto de código. Esta regla mantiene una correspondencia uno a uno entre los puntos de código y sus codificaciones válidas, de modo que hay una codificación válida única para cada punto de código. Esto asegura que las comparaciones y búsquedas de cadenas estén bien definidas.
No todas las secuencias de bytes son UTF-8 válidas. Se debe preparar un decodificador UTF-8 para:
Muchos de los primeros decodificadores UTF-8 los decodificarían, ignorando los bits incorrectos y aceptando resultados demasiado largos. UTF-8 no válido cuidadosamente diseñado podría hacer que se salten o creen caracteres ASCII como NUL, barra o comillas. Se ha utilizado UTF-8 no válido para eludir las validaciones de seguridad en productos de alto perfil, incluido el servidor web IIS de Microsoft y el contenedor de servlets Tomcat de Apache. RFC 3629 establece "Las implementaciones del algoritmo de decodificación DEBEN proteger contra la decodificación de secuencias inválidas". El estándar Unicode requiere que los decodificadores "... traten cualquier secuencia de unidad de código mal formada como una condición de error. Esto garantiza que no interpretará ni emitirá una secuencia de unidad de código mal formada".
Desde RFC 3629 (noviembre de 2003), las mitades sustitutas alta y baja utilizadas por UTF-16 (U + D800 a U + DFFF) y los puntos de código no codificables por UTF-16 (aquellos después de U + 10FFFF) no son valores Unicode legales, y su codificación UTF-8 debe tratarse como una secuencia de bytes no válida. No decodificar las mitades sustitutas no emparejadas hace que sea imposible almacenar UTF-16 no válido (como nombres de archivo de Windows o UTF-16 que se ha dividido entre los sustitutos) como UTF-8, mientras que es posible con WTF-8.
Algunas implementaciones de decodificadores arrojan excepciones a los errores. Esto tiene la desventaja de que puede convertir lo que de otro modo serían errores inofensivos (como un error "no existe tal archivo") en una denegación de servicio. Por ejemplo, las primeras versiones de Python 3.0 se cerrarían inmediatamente si la línea de comandos o las variables de entorno contenían UTF-8 no válido. Una práctica alternativa es reemplazar los errores con un carácter de reemplazo. Desde Unicode 6 (octubre de 2010), el estándar (capítulo 3) ha recomendado una "mejor práctica" en la que el error termina tan pronto como se encuentra un byte no permitido. En estos decodificadores E1, A0, C0 son dos errores (2 bytes en el primero). Esto significa que un error no tiene más de tres bytes de longitud y nunca contiene el comienzo de un carácter válido, y hay 21.952 errores posibles diferentes. El estándar también recomienda reemplazar cada error con el carácter de reemplazo " " (U + FFFD).
Si el carácter de marca de orden de bytes Unicode UTF-16 (BOM, U + FEFF) está al comienzo de un archivo UTF-8, los primeros tres bytes serán 0xEF, 0xBB, 0xBF.
El estándar Unicode no requiere ni recomienda el uso de la lista de materiales para UTF-8, pero advierte que puede encontrarse al comienzo de un archivo transcodificado de otra codificación. Si bien el texto ASCII codificado con UTF-8 es compatible con versiones anteriores de ASCII, esto no es cierto cuando se ignoran las recomendaciones del estándar Unicode y se agrega una lista de materiales. Una lista de materiales puede confundir al software que no está preparado para ello, pero de lo contrario puede aceptar UTF-8, por ejemplo, lenguajes de programación que permiten bytes no ASCII en cadenas literales pero no al principio del archivo. Sin embargo, existía y sigue habiendo software que siempre inserta una lista de materiales al escribir UTF-8 y se niega a interpretar correctamente UTF-8 a menos que el primer carácter sea una lista de materiales (o el archivo solo contenga ASCII).
Algunos lenguajes de programación y formatos de archivo tienen su propia forma de marcar el uso de codificaciones como UTF-8 en el código fuente. Los ejemplos incluyen HTML lt;meta charset="UTF-8"/gt;
y Python 2.7 # coding: utf-8
UTF-8 es la recomendación del WHATWG para las especificaciones HTML y DOM, y el Consorcio de correo de Internet recomienda que todos los programas de correo electrónico puedan mostrar y crear correo utilizando UTF-8. El World Wide Web Consortium recomienda UTF-8 como la codificación predeterminada en XML y HTML (y no solo usando UTF-8, también estableciéndolo en metadatos), "incluso cuando todos los caracteres están en el rango ASCII. . Usando no UTF- 8 codificaciones pueden tener resultados inesperados ". Muchos otros estándares solo admiten UTF-8, por ejemplo, el intercambio JSON abierto lo requiere.
Ver también: Popularidad de codificaciones de textoUTF-8 ha sido la codificación más común para la World Wide Web desde 2008. En octubre de 2021, UTF-8 representa en promedio el 97,3% de todas las páginas web; y 988 de las 1.000 páginas web mejor clasificadas. UTF-8 incluye ASCII como un subconjunto; casi ningún sitio web declara que solo se utiliza ASCII. Varios idiomas tienen un uso 100.0% UTF-8.
Para los archivos de texto locales, el uso de UTF-8 es menor y muchas codificaciones heredadas de un solo byte (y CJK de varios bytes) permanecen en uso. La causa principal son los editores que no muestran ni escriben UTF-8 a menos que el primer carácter en un archivo sea una marca de orden de bytes (BOM), lo que hace imposible que otro software use UTF-8 sin ser reescrito para ignorar la marca de orden de bytes. en la entrada y agréguelo a la salida. Recientemente ha habido algunas mejoras, el Bloc de notas en Windows 10 escribe UTF-8 sin una lista de materiales de forma predeterminada, y algunos archivos del sistema en Windows 11 requieren UTF-8, y casi todos los archivos en macOS y Linux deben ser UTF-8 (sin una lista de materiales). Java, con su API NIO por defecto, lee y escribe archivos UTF-8, y se está moviendo para hacerlo para todas las demás API de archivos. Ya lo hace para todas las API en la mayoría de las plataformas, excepto Windows. "La elección de UTF-8 se aplica solo a las API estándar de Java y no al lenguaje Java, que seguirá utilizando UTF-16". Muchos otros lenguajes de programación utilizan UTF-8 de forma predeterminada para E / S; o planea migrar a UTF-8, como Python, que se está preparando para "cambiar la codificación predeterminada a UTF-8 [ya que] se ha convertido en la codificación de texto estándar de facto". La mayoría de las bases de datos admiten UTF-8 (a veces la única opción como con algunos formatos de archivo), incluida la de Microsoft desde SQL Server 2019, lo que resulta en un aumento de la velocidad del 35% y una "reducción de casi el 50% en los requisitos de almacenamiento".
Internamente, el uso del software es menor, con UTF-16 o UCS-2 en uso, particularmente en Windows, pero también por JavaScript, Python, Qt y muchas otras bibliotecas de software multiplataforma. La compatibilidad con la API de Windows es la razón principal de esto, aunque la creencia de que la indexación directa de BMP mejora la velocidad también fue un factor. El software más reciente ha comenzado a usar UTF-8: la primitiva de cadena predeterminada utilizada en Go, Julia, Rust, Swift 5 y PyPy es UTF-8, una versión futura de Python tiene la intención de almacenar cadenas como UTF-8 y versiones modernas de Microsoft Visual Studio usan UTF-8 internamente (sin embargo, todavía requieren un modificador de línea de comandos para leer o escribir UTF-8). UTF-8 es la "única codificación de texto que debe ser compatible con el estándar C ++", a partir de C ++ 20. A partir de mayo de 2019, Microsoft invirtió su curso de solo admitir UTF-16 para la API de Windows, brindando la capacidad de configurar UTF-8 como la "página de códigos" para la API de varios bytes (anteriormente esto era imposible), y ahora Microsoft recomienda (a los programadores) que utilicen UTF-8 para las aplicaciones de la Plataforma universal de Windows (UWP), sin dejar de mantener una interfaz "Unicode" (que significa UTF-16) heredada.
La Organización Internacional de Normalización (ISO) se propuso componer un conjunto de caracteres universal de múltiples bytes en 1989. El borrador de la norma ISO 10646 contenía un anexo no obligatorio llamado UTF-1 que proporcionaba una codificación de flujo de bytes de sus puntos de código de 32 bits.. Esta codificación no fue satisfactoria por motivos de rendimiento, entre otros problemas, y el mayor problema fue probablemente que no tenía una separación clara entre ASCII y no ASCII: las nuevas herramientas UTF-1 serían compatibles con el texto codificado en ASCII, pero El texto codificado en UTF-1 podría confundir el código existente que espera ASCII (o ASCII extendido ), porque podría contener bytes de continuación en el rango 0x21–0x7E que significan algo más en ASCII, por ejemplo, 0x2F para '/', el separador de directorio de ruta de Unix, y este ejemplo se refleja en el nombre y el texto introductorio de su reemplazo. La siguiente tabla se obtuvo a partir de una descripción textual en el anexo.
Número de bytes | Primer punto de código | Último punto de código | Byte 1 | Byte 2 | Byte 3 | Byte 4 | Byte 5 |
---|---|---|---|---|---|---|---|
1 | U + 0000 | U + 009F | 00–9F | ||||
2 | U + 00A0 | U + 00FF | A0 | A0 – FF | |||
2 | U + 0100 | U + 4015 | A1 – F5 | 21–7E, A0 – FF | |||
3 | U + 4016 | U + 38E2D | F6 – FB | 21–7E, A0 – FF | 21–7E, A0 – FF | ||
5 | U + 38E2E | U + 7FFFFFFF | FC – FF | 21–7E, A0 – FF | 21–7E, A0 – FF | 21–7E, A0 – FF | 21–7E, A0 – FF |
En julio de 1992, el comité X / Open XoJIG buscaba una mejor codificación. Dave Prosser de Unix System Laboratories presentó una propuesta para una que tuviera características de implementación más rápidas e introdujo la mejora de que los caracteres ASCII de 7 bits solo se representarían a sí mismos; todas las secuencias de varios bytes incluirían solo los bytes en los que se estableció el bit alto. El nombre Formato de transformación UCS seguro del sistema de archivos (FSS-UTF) y la mayor parte del texto de esta propuesta se conservaron posteriormente en la especificación final.
Número de bytes | Primer punto de código | Último punto de código | Byte 1 | Byte 2 | Byte 3 | Byte 4 | Byte 5 |
---|---|---|---|---|---|---|---|
1 | U + 0000 | U + 007F | 0xxxxxxx | ||||
2 | U + 0080 | U + 207F | 10xxxxxx | 1xxxxxxx | |||
3 | U + 2080 | U + 8207F | 110xxxxx | 1xxxxxxx | 1xxxxxxx | ||
4 | U + 82080 | U + 208207F | 1110xxxx | 1xxxxxxx | 1xxxxxxx | 1xxxxxxx | |
5 | U + 2082080 | U + 7FFFFFFF | 11110xxx | 1xxxxxxx | 1xxxxxxx | 1xxxxxxx | 1xxxxxxx |
En agosto de 1992, un representante de IBM X / Open distribuyó esta propuesta a las partes interesadas. Una modificación de Ken Thompson del grupo de sistema operativo Plan 9 en Bell Labs lo hizo algo menos eficiente en términos de bits que la propuesta anterior, pero de manera crucial permitió que se sincronizara automáticamente, lo que permite que un lector comience en cualquier lugar y detecte inmediatamente los límites de la secuencia de bytes. También abandonó el uso de sesgos y en su lugar agregó la regla de que solo se permite la codificación más corta posible; la pérdida adicional de compacidad es relativamente insignificante, pero los lectores ahora deben buscar codificaciones no válidas para evitar problemas de confiabilidad y especialmente de seguridad. El diseño de Thompson se describió el 2 de septiembre de 1992 en un mantel individual en un restaurante de Nueva Jersey con Rob Pike. En los días siguientes, Pike y Thompson lo implementaron y actualizaron Plan 9 para usarlo en todo momento, y luego comunicaron su éxito a X / Open, que lo aceptó como la especificación para FSS-UTF.
Número de bytes | Primer punto de código | Último punto de código | Byte 1 | Byte 2 | Byte 3 | Byte 4 | Byte 5 | Byte 6 |
---|---|---|---|---|---|---|---|---|
1 | U + 0000 | U + 007F | 0xxxxxxx | |||||
2 | U + 0080 | U + 07FF | 110xxxxx | 10xxxxxx | ||||
3 | U + 0800 | U + FFFF | 1110xxxx | 10xxxxxx | 10xxxxxx | |||
4 | U + 10000 | U + 1FFFFF | 11110xxx | 10xxxxxx | 10xxxxxx | 10xxxxxx | ||
5 | U + 200000 | U + 3FFFFFF | 111110xx | 10xxxxxx | 10xxxxxx | 10xxxxxx | 10xxxxxx | |
6 | U + 4000000 | U + 7FFFFFFF | 1111110x | 10xxxxxx | 10xxxxxx | 10xxxxxx | 10xxxxxx | 10xxxxxx |
UTF-8 se presentó oficialmente por primera vez en la conferencia USENIX en San Diego, del 25 al 29 de enero de 1993. El Grupo de trabajo de ingeniería de Internet adoptó UTF-8 en su Política sobre conjuntos de caracteres e idiomas en RFC 2277 ( BCP 18) para Internet en el futuro. los estándares funcionan, reemplazando los conjuntos de caracteres de un solo byte como Latin-1 en RFC más antiguos.
En noviembre de 2003, RFC 3629 restringió UTF-8 para coincidir con las restricciones de la codificación de caracteres UTF-16 : prohibir explícitamente los puntos de código correspondientes a los caracteres sustitutos altos y bajos eliminó más del 3% de las secuencias de tres bytes, y terminando en U + 10FFFF eliminó más del 48% de las secuencias de cuatro bytes y todas las secuencias de cinco y seis bytes.
Hay varias definiciones actuales de UTF-8 en varios documentos de estándares:
Reemplazan las definiciones dadas en las siguientes obras obsoletas:
Todos son iguales en su mecánica general, con las principales diferencias en cuestiones como el rango permitido de valores de puntos de código y el manejo seguro de entradas no válidas.
Algunas de las características importantes de esta codificación son las siguientes:
Las siguientes implementaciones muestran ligeras diferencias con la especificación UTF-8. Son incompatibles con la especificación UTF-8 y pueden ser rechazadas por aplicaciones UTF-8 conformes.
El Informe técnico de Unicode n. ° 26 asigna el nombre CESU-8 a una variante no estándar de UTF-8, en la que los caracteres Unicode en planos suplementarios se codifican utilizando seis bytes, en lugar de los cuatro bytes requeridos por UTF-8. La codificación CESU-8 trata cada mitad de un par sustituto UTF-16 de cuatro bytes como un carácter UCS-2 de dos bytes, lo que produce dos caracteres UTF-8 de tres bytes, que juntos representan el carácter suplementario original. Los caracteres Unicode dentro del plano multilingüe básico aparecen como lo harían normalmente en UTF-8. El Informe fue escrito para reconocer y formalizar la existencia de datos codificados como CESU-8, a pesar de que el Consorcio Unicode desalienta su uso, y señala que una posible razón intencional para la codificación CESU-8 es la preservación de la intercalación binaria UTF-16.
La codificación CESU-8 puede resultar de la conversión de datos UTF-16 con caracteres suplementarios a UTF-8, utilizando métodos de conversión que asumen datos UCS-2, lo que significa que desconocen los caracteres suplementarios UTF-16 de cuatro bytes. Es principalmente un problema en los sistemas operativos que usan UTF-16 internamente, como Microsoft Windows.
En Oracle Database, el UTF8
juego de caracteres usa codificación CESU-8 y está en desuso. El AL32UTF8
juego de caracteres utiliza codificación UTF-8 compatible con los estándares y es el preferido.
CESU-8 está prohibido para su uso en documentos HTML5.
En MySQL, el utf8mb3
conjunto de caracteres se define como datos codificados en UTF-8 con un máximo de tres bytes por carácter, lo que significa que solo se admiten caracteres Unicode en el plano multilingüe básico (es decir, de UCS-2 ). Los caracteres Unicode en planos suplementarios no se admiten explícitamente. utf8mb3
está en desuso en favor del utf8mb4
juego de caracteres, que utiliza codificación UTF-8 compatible con los estándares. utf8
es un alias de utf8mb3
, pero está destinado a convertirse en un alias de utf8mb4
en una versión futura de MySQL. Es posible, aunque no es compatible, almacenar datos codificados en CESU-8 utf8mb3
, manejando datos UTF-16 con caracteres suplementarios como si fuera UCS-2.
UTF-8 modificado (MUTF-8) se originó en el lenguaje de programación Java. En UTF-8 modificado, el carácter nulo (U + 0000) utiliza la codificación demasiado larga de dos bytes 110 00000 10 000000 (hexadecimal C0 80), en lugar de 00000000 (hexadecimal 00). Las cadenas UTF-8 modificadas nunca contienen bytes nulos reales, pero pueden contener todos los puntos de código Unicode, incluido U + 0000, lo que permite que dichas cadenas (con un byte nulo agregado) sean procesadas por las funciones tradicionales de cadenas terminadas en nulo. Todas las implementaciones de UTF-8 modificadas conocidas también tratan los pares sustitutos como en CESU-8.
En uso normal, el lenguaje admite UTF-8 estándar al leer y escribir cadenas a través de InputStreamReader
y OutputStreamWriter
(si es el juego de caracteres predeterminado de la plataforma o según lo solicite el programa). Sin embargo, utiliza UTF-8 modificado para la serialización de objetos entre otras aplicaciones de DataInput
y DataOutput
, para la interfaz nativa de Java, y para incrustar cadenas constantes en archivos de clase.
El formato dex definido por Dalvik también usa el mismo UTF-8 modificado para representar valores de cadena. Tcl también usa el mismo UTF-8 modificado que Java para la representación interna de datos Unicode, pero usa CESU-8 estricto para datos externos.
En WTF-8 (formato de transformación oscilante, 8 bits) se permiten mitades sustitutas no emparejadas (U + D800 a U + DFFF). Esto es necesario para almacenar UTF-16 posiblemente no válido, como nombres de archivo de Windows. Muchos sistemas que tratan con UTF-8 funcionan de esta manera sin considerarlo una codificación diferente, ya que es más simple.
(El término "WTF-8" también se ha utilizado con humor para referirse a UTF-8 erróneamente codificado doblemente, a veces con la implicación de que los bytes CP1252 son los únicos codificados).
La versión 3 del lenguaje de programación Python trata cada byte de una secuencia de bytes UTF-8 no válida como un error (vea también los cambios con el nuevo modo UTF-8 en Python 3.7); esto da 128 posibles errores diferentes. Se han creado extensiones para permitir que cualquier secuencia de bytes que se asume que es UTF-8 se transforme sin pérdidas a UTF-16 o UTF-32, traduciendo los 128 bytes de error posibles en puntos de código reservados y transformando esos puntos de código de nuevo en error. bytes para generar UTF-8. El enfoque más común es traducir los códigos a U + DC80... U + DCFF que son valores sustitutos bajos (finales) y, por lo tanto, UTF-16 "no válido", como lo usa el PEP 383 de Python (o "escape sustituto") Acercarse. Otra codificación llamada MirBSD OPTU-8/16 los convierte a U + EF80... U + EFFF en un área de uso privado. En cualquier enfoque, el valor del byte se codifica en los ocho bits inferiores del punto de código de salida.
Estas codificaciones son muy útiles porque evitan la necesidad de tratar con cadenas de bytes "no válidas" hasta mucho más tarde, si es que lo hacen, y permiten que las matrices de bytes de "texto" y "datos" sean el mismo objeto. Si un programa quiere usar UTF-16 internamente, estos son necesarios para preservar y usar nombres de archivo que pueden usar UTF-8 no válido; como la API del sistema de archivos de Windows usa UTF-16, la necesidad de admitir UTF-8 no válido es menor.
Para que la codificación sea reversible, las codificaciones UTF-8 estándar de los puntos de código utilizados para bytes erróneos deben considerarse inválidas. Esto hace que la codificación sea incompatible con WTF-8 o CESU-8 (aunque solo para 128 puntos de código). Al volver a codificar, es necesario tener cuidado con las secuencias de puntos de código de error que se vuelven a convertir en UTF-8 válido, que puede ser utilizado por software malintencionado para obtener caracteres inesperados en la salida, aunque esto no puede producir caracteres ASCII, por lo que se considera comparativamente seguro, ya que las secuencias maliciosas (como las secuencias de comandos entre sitios ) generalmente se basan en caracteres ASCII.