what java unicode utf-8 utf-16 utf

java - what is xml



Diferencia entre UTF-8 y UTF-16? (4)

Diferencia entre UTF-8 y UTF-16? ¿Por qué los necesitamos?

MessageDigest md = MessageDigest.getInstance("SHA-256"); String text = "This is some text"; md.update(text.getBytes("UTF-8")); // Change this to "UTF-16" if needed byte[] digest = md.digest();


Creo que hay muchos buenos artículos sobre esto en la Web, pero aquí hay un breve resumen.

Tanto UTF-8 como UTF-16 son codificaciones de longitud variable. Sin embargo, en UTF-8 un personaje puede ocupar un mínimo de 8 bits, mientras que en UTF-16 la longitud del carácter comienza con 16 bits.

Principales profesionales de UTF-8:

  • Los caracteres ASCII básicos como dígitos, caracteres latinos sin acentos, etc. ocupan un byte que es idéntico a la representación de US-ASCII. De esta forma, todas las cadenas de caracteres US-ASCII se convierten en UTF-8 válidas, lo que proporciona una retrocompatibilidad decente en muchos casos.
  • Sin bytes nulos, lo que permite utilizar cadenas terminadas en nulo, esto también ofrece una gran compatibilidad hacia atrás.
  • UTF-8 es independiente del orden de bytes, por lo que no tiene que preocuparse por el problema de Big Endian / Little Endian.

Principales contras UTF-8:

  • Muchos caracteres comunes tienen diferente longitud, lo que ralentiza la indexación por punto de código y calcula un recuento de punto de código terriblemente.
  • Aunque el orden de bytes no importa, a veces UTF-8 todavía tiene BOM (marca de orden de bytes) que sirve para notificar que el texto está codificado en UTF-8, y también rompe la compatibilidad con el software ASCII incluso si el texto solo contiene caracteres ASCII . El software de Microsoft (como el Bloc de notas) especialmente le gusta agregar listas de materiales a UTF-8.

Principales profesionales de UTF-16:

  • Los caracteres BMP (plano multilingüe básico), incluidos el latín, el cirílico y la mayoría de los chinos (el PRC hizo obligatorio el uso de algunos puntos de código fuera de BMP), la mayoría de los japoneses se pueden representar con 2 bytes. Esto acelera la indexación y el cálculo del conteo del punto de código en caso de que el texto no contenga caracteres suplementarios.
  • Incluso si el texto tiene caracteres suplementarios, todavía están representados por pares de valores de 16 bits, lo que significa que la longitud total aún es divisible por dos y permite usar caracteres de 16 bits como el componente primitivo de la cadena.

Principales inconvenientes UTF-16:

  • Muchos bytes nulos en cadenas US-ASCII, lo que significa que no hay cadenas terminadas en nulo y mucha memoria desperdiciada.
  • Usarlo como codificación de longitud fija "funciona en su mayoría" en muchos escenarios comunes (especialmente en EE. UU./UE / países con alfabetos cirílicos / Israel / países árabes / Irán y muchos otros), lo que a menudo conduce a un soporte defectuoso donde no lo hace. Esto significa que los programadores deben conocer los pares de sustitución y manejarlos adecuadamente en los casos en que sea importante.
  • Es de longitud variable, por lo que contar o indexar puntos de código es costoso, aunque menor que UTF-8.

En general, UTF-16 es generalmente mejor para la representación en memoria porque BE / LE es irrelevante allí (solo usa orden nativo) y la indexación es más rápida (simplemente no te olvides de manejar los pares de sustitución correctamente). UTF-8, por otro lado, es extremadamente bueno para archivos de texto y protocolos de red porque no hay un problema BE / LE y la terminación nula a menudo es útil, así como la compatibilidad ASCII.


Esto no está relacionado con UTF-8/16 (en general, aunque se convierte a UTF16 y la parte BE / LE puede configurarse con una sola línea), sin embargo, a continuación se muestra la forma más rápida de convertir Cadena en byte []. Por ejemplo: bueno exactamente para el caso provisto (código hash). String.getBytes (enc) es relativamente lento.

static byte[] toBytes(String s){ byte[] b=new byte[s.length()*2]; ByteBuffer.wrap(b).asCharBuffer().put(s); return b; }


Simplemente son esquemas diferentes para representar caracteres Unicode.

Ambos son de longitud variable: UTF-16 utiliza 2 bytes para todos los caracteres en el plano multilingüe básico (BMP) que contiene la mayoría de los caracteres de uso común.

UTF-8 usa entre 1 y 3 bytes para los caracteres en el BMP, hasta 4 para los caracteres en el rango Unicode actual de U + 0000 a U + 1FFFFF, y es extensible hasta U + 7FFFFFFF si es necesario alguna vez ... pero notablemente todos los caracteres ASCII se representan en un solo byte cada uno.

A los efectos de un resumen de mensaje, no importará cuál de estos elija, siempre que todos los que intenten recrear el resumen usen la misma opción.

Consulte esta página para obtener más información sobre UTF-8 y Unicode.

(Tenga en cuenta que todos los caracteres de Java son puntos de código UTF-16 dentro del BMP, para representar caracteres por encima de U + FFFF necesita usar pares de sustitución en Java).


Una forma simple de diferenciar UTF-8 y UTF-16 es identificar puntos en común entre ellos.

Además de compartir el mismo número Unicode para un personaje dado, cada uno es su propio formato.