utf-8 - codificaciones - utf-64
¿Cuál es el punto de UTF-16? (5)
Nunca entendí el sentido de la codificación UTF-16. Si necesita poder tratar cadenas como acceso aleatorio (es decir, un punto de código es lo mismo que una unidad de código), entonces necesita UTF-32, ya que UTF-16 todavía es de longitud variable. Si no necesita esto, entonces UTF-16 parece una pérdida de espacio colosal en comparación con UTF-8. ¿Cuáles son las ventajas de UTF-16 sobre UTF-8 y UTF-32 y por qué Windows y Java lo usan como su codificación nativa?
Cuando se diseñó Windows NT, UTF-16 no existía (NT 3.51 nació en 1993, mientras que UTF-16 nació en 1996 con el estándar Unicode 2.0); en cambio, había UCS-2, que, en ese momento, era suficiente para contener todos los caracteres disponibles en Unicode, por lo que el 1 punto de código = 1 unidad de código de equivalencia era realmente cierto, no se necesita lógica de longitud variable para las cadenas.
Se movieron a UTF-16 más tarde, para admitir todo el juego de caracteres Unicode; sin embargo, no pudieron pasar a UTF-8 ni a UTF-32, porque esto habría roto la compatibilidad binaria en la interfaz API (entre otras cosas).
En cuanto a Java, no estoy realmente seguro; desde que fue lanzado en ~ 1995, sospecho que UTF-16 ya estaba en el aire (incluso si aún no estaba estandarizado), pero creo que la compatibilidad con los sistemas operativos basados en NT puede haber jugado algún papel en su elección (continuo Las conversiones UTF-8 <-> UTF-16 para cada llamada a las API de Windows pueden presentar cierta desaceleración).
Editar
Wikipedia explica que incluso para Java fue del mismo modo: originalmente era compatible con UCS-2, pero se movió a UTF-16 en J2SE 5.0.
Entonces, en general, cuando ve UTF-16 en alguna API / Framework es porque comenzó como UCS-2 (para evitar complicaciones en los algoritmos de administración de cadenas) pero se movió a UTF-16 para admitir los puntos de código fuera del BMP, manteniendo el mismo tamaño de unidad de código.
Ninguna de las respuestas que indican una ventaja de UTF-16 sobre UTF-8 tiene sentido, a excepción de la respuesta de compatibilidad hacia atrás.
Bueno, hay dos advertencias a mi comentario.
Erik afirma: "UTF-16 cubre todo el BMP con unidades individuales: a menos que necesites los caracteres más raros fuera del BMP, UTF-16 tiene efectivamente 2 bytes por carácter".
Advertencia 1)
Si puede estar seguro de que su aplicación NUNCA necesitará ningún personaje fuera del BMP, y que cualquier código de biblioteca que escriba para usarlo NUNCA se utilizará con ninguna aplicación que necesite un personaje fuera del BMP, entonces podría usar UTF-16, y escribir código que hace la suposición implícita de que cada carácter tendrá exactamente dos bytes de longitud.
Eso parece extremadamente peligroso (en realidad, estúpido).
Si su código asume que todos los caracteres UTF-16 tienen dos bytes de longitud, y su programa interactúa con una aplicación o biblioteca donde hay un solo carácter fuera del BMP, entonces su código se romperá. El código que examina o manipula UTF-16 se debe escribir para manejar el caso de un carácter UTF-16 que requiera más de 2 bytes; por lo tanto, estoy "descartando" esta advertencia.
UTF-16 no es más fácil de codificar que UTF-8 (el código para ambos debe manejar caracteres de longitud variable).
Advertencia 2)
UTF-16 PODRÍA ser más eficiente computacionalmente, en algunas circunstancias, si está escrito adecuadamente.
De esta manera: supongamos que ciertas cadenas largas rara vez se modifican, pero a menudo se examinan (o mejor, nunca se modifican una vez construidas, es decir, un generador de cadenas que crea cadenas no modificables). Se podría establecer un indicador para cada cadena, indicando si la cadena contiene solo caracteres de "longitud fija" (es decir, no contiene caracteres que no tienen exactamente dos bytes de longitud). Las cadenas para las que la bandera es verdadera se pueden examinar con un código optimizado que asume caracteres de longitud fija (2 bytes).
¿Qué hay de la eficiencia del espacio?
UTF-16 es, obviamente, más eficiente para A) caracteres para los cuales UTF-16 requiere menos bytes para codificar que UTF-8.
UTF-8 es, obviamente, más eficiente para B) caracteres para los cuales UTF-8 requiere menos bytes para codificar que UTF-16.
Excepto por un texto muy "especializado", es probable que el recuento (B) supere con creces el recuento (A).
UTF-16 cubre todo el BMP con unidades individuales. Por lo tanto, a menos que necesite los caracteres más raros fuera del BMP, UTF-16 tiene efectivamente 2 bytes por carácter. UTF-32 requiere más espacio, UTF-8 requiere soporte de longitud variable.
UTF-16 permite que todo el plano multilingüe básico (BMP) se represente como unidades de código único. Los puntos de código Unicode más allá de U + FFFF están representados por pares de sustitución.
Lo interesante es que Java y Windows (y otros sistemas que usan UTF-16) operan todos al nivel de unidad de código, no al nivel de punto de código Unicode. Por lo tanto, la cadena que consta del carácter único U + 1D122 (SÍMBOLO MUSICAL F CLEF) se codifica en Java como "/ ud824 / udd22" y "/ud824/udd22".length() == 2
(no 1
). Entonces es como un truco, pero resulta que los caracteres no son de longitud variable.
La ventaja de UTF-16 sobre UTF-8 es que uno cedería demasiado si se utilizara el mismo hack con UTF-8.
UTF16 se usa generalmente como una asignación directa a conjuntos de caracteres de múltiples bytes, es decir, onyl los caracteres asignados 0-0xFFFF originales.
Esto te da lo mejor de ambos mundos, has fijado el tamaño del personaje pero aún puedes imprimir todos los caracteres que cualquiera pueda usar (exceptuando los ortodoxos Klingon religous scripts)