UTF-16 - UTF-16

UTF-16
Unifont Full Map.png
Los primeros 2 16 puntos de código Unicode. La franja de color gris sólido cerca de la parte inferior son las mitades sustitutas utilizadas por UTF-16 (la región blanca debajo de la franja es el área de uso privado )
Idioma (s) Internacional
Estándar Estándar Unicode
Clasificación Formato de transformación Unicode , codificación de ancho variable
Se extiende UCS-2
Transforma / Codifica ISO 10646 ( Unicode )

UTF-16 ( formato de transformación Unicode de 16 bits ) es una codificación de caracteres capaz de codificar todos los 1,112,064 puntos de código de caracteres válidos de Unicode (de hecho, este número de puntos de código está dictado por el diseño de UTF-16). La codificación es de longitud variable , ya que los puntos de código se codifican con una o dos unidades de código de 16 bits . UTF-16 surgió de una codificación de 16 bits de ancho fijo obsoleta anterior, ahora conocida como UCS-2 (para juego de caracteres universal de 2 bytes), una vez que quedó claro que se necesitaban más de 2 16 (65,536) puntos de código.

UTF-16 es utilizado internamente por sistemas como Microsoft Windows , el lenguaje de programación Java y JavaScript / ECMAScript. También se utiliza a menudo para texto sin formato y para archivos de datos de procesamiento de texto en Microsoft Windows. Rara vez se usa para archivos en sistemas similares a Unix. A partir de mayo de 2019, Microsoft revirtió su curso de solo enfatizar UTF-16 para Unicode; para aplicaciones de Windows, Microsoft recomienda y admite UTF-8 (por ejemplo, para aplicaciones de la Plataforma universal de Windows (UWP)).

UTF-16 es la única codificación web incompatible con ASCII y nunca ganó popularidad en la web, donde es utilizada por menos del 0,002% (poco más de la milésima parte del 1 por ciento) de las páginas web. UTF-8 , en comparación, es utilizado por el 97% de todas las páginas web. El Grupo de Trabajo de Tecnología de Aplicación de Hipertexto Web (WHATWG) considera que UTF-8 es "la codificación obligatoria para todo [texto]" y que, por razones de seguridad, las aplicaciones de navegador no deben usar UTF-16.

Historia

A fines de la década de 1980, se comenzó a trabajar en el desarrollo de una codificación uniforme para un "Conjunto de caracteres universal" ( UCS ) que reemplazaría las codificaciones anteriores específicas del idioma con un sistema coordinado. El objetivo era incluir todos los caracteres requeridos de la mayoría de los idiomas del mundo, así como símbolos de dominios técnicos como ciencia, matemáticas y música. La idea original era reemplazar las codificaciones típicas de 256 caracteres, que requerían 1 byte por carácter, con una codificación que usaba 65.536 (2 16 ) valores, lo que requeriría 2 bytes (16 bits) por carácter.

Dos grupos trabajaron en esto en paralelo, ISO / IEC JTC 1 / SC 2 y el Consorcio Unicode , este último representando principalmente a los fabricantes de equipos informáticos. Los dos grupos intentaron sincronizar sus asignaciones de caracteres para que las codificaciones en desarrollo fueran mutuamente compatibles. La codificación inicial de 2 bytes se llamaba originalmente "Unicode", pero ahora se llama "UCS-2".

Cuando quedó cada vez más claro que 2 16 caracteres no serían suficientes, IEEE introdujo un espacio más grande de 31 bits y una codificación ( UCS-4 ) que requeriría 4 bytes por carácter. Esto fue resistido por el Consorcio Unicode , tanto porque 4 bytes por carácter desperdiciaban mucha memoria y espacio en disco, como porque algunos fabricantes ya habían invertido mucho en la tecnología de 2 bytes por carácter. El esquema de codificación UTF-16 se desarrolló como un compromiso y se introdujo con la versión 2.0 del estándar Unicode en julio de 1996. Está completamente especificado en RFC 2781, publicado en 2000 por el IETF .

En la codificación UTF-16, los puntos de código inferiores a 2 16 se codifican con una única unidad de código de 16 bits igual al valor numérico del punto de código, como en el UCS-2 anterior. Los puntos de código más nuevos mayores o iguales que 2 16 se codifican mediante un valor compuesto utilizando dos unidades de código de 16 bits. Estas dos unidades de código de 16 bits se eligen del rango sustituto UTF-16 0xD800–0xDFFF que no se había asignado previamente a caracteres. Los valores de este rango no se utilizan como caracteres y UTF-16 no proporciona una forma legal de codificarlos como puntos de código individuales. Un flujo UTF-16, por lo tanto, consta de puntos de código únicos de 16 bits fuera del rango sustituto para puntos de código en el plano multilingüe básico (BMP) y pares de valores de 16 bits dentro del rango sustituto para puntos de código por encima del BMP.

UTF-16 se especifica en las últimas versiones tanto del estándar internacional ISO / IEC 10646 como del estándar Unicode. "UCS-2 ahora debería considerarse obsoleto. Ya no se refiere a una forma de codificación en 10646 o en el estándar Unicode". A partir de 2021, no hay planes para extender UTF-16 para admitir una mayor cantidad de puntos de código o los puntos de código reemplazados por sustitutos, ya que esto violaría la Política de estabilidad Unicode con respecto a la categoría general o los puntos de código sustitutos. (Cualquier esquema que siga siendo un código de sincronización automática requeriría asignar al menos un punto de código BMP para iniciar una secuencia. No se permite cambiar el propósito de un punto de código).

Descripción

Cada punto de código Unicode se codifica como una o dos unidades de código de 16 bits . La forma en que estos códigos de 16 bits se almacenan como bytes depende de la ' endianidad ' del archivo de texto o del protocolo de comunicación.

Un "carácter" puede necesitar desde dos bytes hasta catorce o incluso más bytes para ser registrado. Por ejemplo, un carácter de bandera emoji toma 8 bytes, ya que está "construido a partir de un par de valores escalares Unicode" (y esos valores están fuera del BMP y requieren 4 bytes cada uno).

U + 0000 a U + D7FF y U + E000 a U + FFFF

Tanto UTF-16 como UCS-2 codifican puntos de código en este rango como unidades de código individuales de 16 bits que son numéricamente iguales a los puntos de código correspondientes. Estos puntos de código en el plano multilingüe básico (BMP) son los únicos puntos de código que se pueden representar en UCS-2. A partir de Unicode 9.0, algunos scripts modernos no latinos de Asia, Oriente Medio y África quedan fuera de este rango, al igual que la mayoría de los caracteres emoji .

Puntos de código de U + 010000 a U + 10FFFF

Los puntos de código de los otros planos (denominados planos suplementarios ) se codifican como dos unidades de código de 16 bits denominadas par sustituto , mediante el siguiente esquema:

Decodificador UTF-16
Bajo
Elevado
DC00 DC01    ...    DFFF
D800 010000 010001 ... 0103FF
D801 010400 010401 ... 0107FF
  ⋮
DBFF 10FC00 10FC01 ... 10FFFF
  • 0x10000 se resta del punto de código (U) , dejando un número de 20 bits (U ') en el rango de números hexadecimales 0x00000–0xFFFFF. Tenga en cuenta que para estos fines, U se define como no mayor que 0x10FFFF.
  • Los diez bits más altos (en el rango 0x000–0x3FF) se agregan a 0xD800 para dar la primera unidad de código de 16 bits o sustituto alto (W1) , que estará en el rango 0xD800–0xDBFF .
  • Los diez bits bajos (también en el rango 0x000–0x3FF) se agregan a 0xDC00 para dar la segunda unidad de código de 16 bits o sustituto bajo (W2) , que estará en el rango 0xDC00–0xDFFF .

Ilustrada visualmente, la distribución de U ' entre W1 y W2 se ve así:

U' = yyyyyyyyyyxxxxxxxxxx  // U - 0x10000
W1 = 110110yyyyyyyyyy      // 0xD800 + yyyyyyyyyy
W2 = 110111xxxxxxxxxx      // 0xDC00 + xxxxxxxxxx

El sustituto alto y el sustituto bajo también se conocen como sustitutos "iniciales" y "finales", respectivamente, análogos a los bytes iniciales y finales de UTF-8.

Dado que los rangos para los sustitutos altos ( 0xD800–0xDBFF ), los sustitutos bajos ( 0xDC00–0xDFFF ) y los caracteres BMP válidos (0x0000–0xD7FF, 0xE000–0xFFFF) son inconexos , no es posible que un sustituto coincida con un carácter BMP, o que dos unidades de código adyacentes parezcan un par sustituto legal . Esto simplifica mucho las búsquedas. También significa que UTF-16 se sincroniza automáticamente en palabras de 16 bits: si una unidad de código inicia un carácter se puede determinar sin examinar unidades de código anteriores (es decir, el tipo de unidad de código se puede determinar por los rangos de valores en los que se caídas). UTF-8 comparte estas ventajas, pero muchos esquemas de codificación de múltiples bytes anteriores (como Shift JIS y otras codificaciones asiáticas de múltiples bytes) no permitían una búsqueda inequívoca y solo podían sincronizarse volviendo a analizar desde el principio de la cadena (UTF -16 no se sincroniza automáticamente si se pierde un byte o si el recorrido comienza en un byte aleatorio).

Debido a que los caracteres más utilizados están todos en el BMP, el manejo de pares sustitutos a menudo no se prueba a fondo. Esto conduce a errores persistentes y posibles agujeros de seguridad, incluso en software de aplicación popular y bien revisado (por ejemplo, CVE - 2008-2938 , CVE - 2012-2135 ).

Los planos suplementarios contienen emoji , escrituras históricas, símbolos menos utilizados, ideogramas chinos menos utilizados, etc. Dado que la codificación de los planos suplementarios contiene 20 bits significativos (10 de 16 bits en cada uno de los sustitutos alto y bajo ), 2 20 puntos de código pueden estar codificados, divididos en 16 planos de 2 16 puntos de código cada uno. Incluyendo el avión básico multilingüe manejado por separado, hay un total de 17 aviones.

U + D800 a U + DFFF

El estándar Unicode reserva permanentemente estos valores de puntos de código para la codificación UTF-16 de los sustitutos alto y bajo, y nunca se les asignará un carácter, por lo que no debería haber ninguna razón para codificarlos. El estándar oficial Unicode dice que ningún formulario UTF, incluido UTF-16, puede codificar estos puntos de código.

Sin embargo, UCS-2, UTF-8 y UTF-32 pueden codificar estos puntos de código de formas triviales y obvias, y una gran cantidad de software lo hace, aunque el estándar establece que tales disposiciones deben tratarse como errores de codificación.

Es posible codificar sin ambigüedades un sustituto no apareado (un punto de código sustituto alto no seguido por uno bajo, o uno bajo no precedido por uno alto) en el formato de UTF-16 usando una unidad de código igual al punto de código. . El resultado no es UTF-16 válido, pero la mayoría de las implementaciones de codificadores y decodificadores UTF-16 hacen esto al traducir entre codificaciones. Windows permite sustitutos no emparejados en nombres de archivo y otros lugares, lo que generalmente significa que deben ser compatibles con software a pesar de su exclusión del estándar Unicode.

Ejemplos de

Para codificar U + 10437 (𐐷) a UTF-16:

  • Reste 0x10000 del punto de código, dejando 0x0437.
  • Para el sustituto alto, cambie a la derecha por 10 (divida por 0x400), luego agregue 0xD800, lo que da como resultado 0x0001 + 0xD800 = 0xD801.
  • Para el sustituto bajo, tome los 10 bits bajos (el resto de dividir por 0x400), luego agregue 0xDC00, lo que da como resultado 0x0037 + 0xDC00 = 0xDC37.

Para decodificar U + 10437 (𐐷) desde UTF-16:

  • Tome el sustituto alto (0xD801) y reste 0xD800, luego multiplique por 0x400, lo que da como resultado 0x0001 × 0x400 = 0x0400.
  • Tome el sustituto bajo (0xDC37) y reste 0xDC00, lo que da como resultado 0x37.
  • Sume estos dos resultados juntos (0x0437) y finalmente agregue 0x10000 para obtener el punto de código UTF-32 decodificado final, 0x10437.

La siguiente tabla resume esta conversión, así como otras. Los colores indican cómo se distribuyen los bits del punto de código entre los bytes UTF-16. Los bits adicionales agregados por el proceso de codificación UTF-16 se muestran en negro.

Personaje Punto de código binario Binario UTF-16
Unidades de código hexadecimal UTF-16
Bytes
hexadecimales UTF-16BE
Bytes
hexadecimales UTF-16LE
PS U+0024 0000 0000 0010 0100 0000 0000 0010 0100 0024 00 24 24 00
U+20AC 0010 0000 1010 1100 0010 0000 1010 1100 20AC 20 AC AC 20
𐐷 U+10437 0001 0000 0100 0011 0111 1101 1000 0000 0001 1101 1100 0011 0111 D801 DC37 D8 01 DC 37 01 D8 37 DC
𤭢 U+24B62 0010 0100 1011 0110 0010 1101 1000 0101 0010 1101 1111 0110 0010 D852 DF62 D8 52 DF 62 52 D8 62 DF

Esquemas de codificación por orden de bytes

UTF-16 y UCS-2 producen una secuencia de unidades de código de 16 bits. Dado que la mayoría de los protocolos de comunicación y almacenamiento se definen para bytes, y cada unidad toma dos bytes de 8 bits, el orden de los bytes puede depender del endianness (orden de bytes) de la arquitectura de la computadora.

Para ayudar a reconocer el orden de bytes de las unidades de código, UTF-16 permite que una marca de orden de bytes (BOM), un punto de código con el valor U + FEFF, preceda al primer valor codificado real. (U + FEFF es el espacio sin ruptura invisible de ancho cero / carácter ZWNBSP). Si la arquitectura endian del decodificador coincide con la del codificador, el decodificador detecta el valor 0xFEFF, pero un decodificador endian opuesto interpreta la lista de materiales como la valor sin carácter U + FFFE reservado para este propósito. Este resultado incorrecto proporciona una sugerencia para realizar un intercambio de bytes para los valores restantes.

Si falta la lista de materiales, RFC 2781 recomienda que se asuma la codificación big-endian. En la práctica, debido a que Windows usa el orden little-endian de forma predeterminada, muchas aplicaciones asumen la codificación little-endian. También es confiable para detectar endianness buscando bytes nulos, asumiendo que los caracteres menores a U + 0100 son muy comunes. Si más bytes pares (comenzando en 0) son nulos, entonces es big-endian.

El estándar también permite que el orden de los bytes se establezca explícitamente especificando UTF-16BE o UTF-16LE como tipo de codificación. Cuando el orden de los bytes se especifica explícitamente de esta manera, no se supone específicamente que una lista de materiales se anteponga al texto, y un U + FEFF al principio debe manejarse como un carácter ZWNBSP. La mayoría de las aplicaciones ignoran una lista de materiales en todos los casos a pesar de esta regla.

Para los protocolos de Internet , IANA ha aprobado "UTF-16", "UTF-16BE" y "UTF-16LE" como nombres para estas codificaciones (los nombres no distinguen entre mayúsculas y minúsculas). Los alias UTF_16 o UTF16 pueden ser significativos en algunos lenguajes de programación o aplicaciones de software, pero no son nombres estándar en los protocolos de Internet.

Se utilizan designaciones similares, UCS-2BE y UCS-2LE , para mostrar versiones de UCS-2 .

Uso

UTF-16 se utiliza para texto en la API del sistema operativo de todas las versiones actualmente admitidas de Microsoft Windows (e incluidas al menos todas desde Windows CE / 2000 / XP / 2003 / Vista / 7 ), incluido Windows 10 . En Windows XP, no se incluye ningún punto de código por encima de U + FFFF en ninguna fuente entregada con Windows para idiomas europeos. Los sistemas Windows NT más antiguos (anteriores a Windows 2000) solo son compatibles con UCS-2. Los archivos y los datos de red tienden a ser una combinación de codificaciones de bytes UTF-16, UTF-8 y heredadas.

Si bien ha habido algo de compatibilidad con UTF-8 incluso para Windows XP, se mejoró (en particular, la capacidad de nombrar un archivo usando UTF-8) en Windows 10 insider build 17035 y la actualización de abril de 2018, y a partir de mayo de 2019 Microsoft recomienda el software utilícelo en lugar de UTF-16.

El sistema operativo IBM i designa CCSID ( página de códigos ) 13488 para la codificación UCS-2 y CCSID 1200 para la codificación UTF-16, aunque el sistema los trata a ambos como UTF-16.

UTF-16 es utilizado por los sistemas operativos Qualcomm BREW ; los entornos .NET ; y el kit de herramientas de widget gráfico multiplataforma de Qt .

El sistema operativo Symbian utilizado en los teléfonos Nokia S60 y los teléfonos Sony Ericsson UIQ usa UCS-2. Los teléfonos iPhone utilizan UTF-16 para el servicio de mensajes cortos en lugar de UCS-2 descrito en los estándares 3GPP TS 23.038 ( GSM ) e IS-637 ( CDMA ).

El sistema de archivos Joliet , que se utiliza en los medios de CD-ROM , codifica los nombres de los archivos mediante UCS-2BE (hasta sesenta y cuatro caracteres Unicode por nombre de archivo).

El entorno del lenguaje Python oficialmente solo usa UCS-2 internamente desde la versión 2.0, pero el decodificador UTF-8 para "Unicode" produce UTF-16 correcto. Desde Python 2.2, se admiten compilaciones "amplias" de Unicode que utilizan UTF-32 en su lugar; estos se utilizan principalmente en Linux. Python 3.3 ya no usa UTF-16, sino que se elige una codificación que brinda la representación más compacta para la cadena dada entre ASCII / Latin-1, UCS-2 y UTF-32.

Java usó originalmente UCS-2 y agregó soporte de caracteres suplementarios UTF-16 en J2SE 5.0 .

JavaScript puede usar UCS-2 o UTF-16. A partir de ES2015, se han agregado métodos de cadena y marcas de expresión regular al lenguaje que permiten manejar cadenas desde una perspectiva independiente de la codificación.

En muchos idiomas, las cadenas entre comillas necesitan una nueva sintaxis para citar caracteres que no son BMP, ya que la "\uXXXX"sintaxis de estilo C se limita explícitamente a 4 dígitos hexadecimales. Los siguientes ejemplos ilustran la sintaxis del carácter no BMP "𝄞" (U + 1D11E, SÍMBOLO MUSICAL G CLEF). El más común (usado por C ++ , C # , D y varios otros lenguajes) es usar una 'U' mayúscula con 8 dígitos hexadecimales como "\U0001D11E". En las expresiones regulares de Java 7, ICU y Perl, se "\x{1D11E}"debe utilizar la sintaxis ; de manera similar, en ECMAScript 2015 (JavaScript), el formato de escape es "\u{1D11E}". En muchos otros casos (como Java fuera de las expresiones regulares), la única forma de obtener caracteres que no sean BMP es ingresar las mitades sustitutas individualmente, por ejemplo: "\uD834\uDD1E"para U + 1D11E.

Las implementaciones de cadenas basadas en UTF-16 normalmente definen las longitudes de la cadena y permiten la indexación en términos de estas unidades de código de 16 bits , no en términos de puntos de código. Ni los puntos de código ni las unidades de código corresponden a nada que un usuario final pueda reconocer como un "carácter"; las cosas que los usuarios identifican como caracteres pueden, en general, consistir en un punto de código base y una secuencia de caracteres combinados (o puede ser una secuencia de puntos de código de algún otro tipo, por ejemplo Hangul uniendo jamos) - Unicode se refiere a esta construcción como un grafema cluster  - y como tal, las aplicaciones que manejan cadenas Unicode, cualquiera que sea la codificación, deben hacer frente al hecho de que esto limita su capacidad para dividir y combinar cadenas arbitrariamente.

UCS-2 también es compatible con el lenguaje PHP y MySQL.

Swift , versión 5, el idioma de aplicación preferido de Apple, cambió de UTF-16 a UTF-8 como codificación preferida.

Ver también

Notas

Referencias

enlaces externos