2008-10-02 10 views
11

Sé que es habitual, pero ¿por qué? ¿Existen razones técnicas reales por las que cualquier otra forma sería una mala idea o se basa solo en la historia de la codificación y la compatibilidad con versiones anteriores? Además, ¿cuáles son los peligros de no usar UTF-8, pero alguna otra codificación (más notablemente, UTF-16)?¿Por qué la codificación UTF-8 se utiliza al interactuar con un entorno UNIX/Linux?

Editar: Al interactuar, me refiero principalmente a shell y libc.

Respuesta

15

En parte porque los sistemas de archivos esperan que los bytes NUL ('\ 0') terminen los nombres de los archivos, por lo que UTF-16 no funcionaría bien. Tendría que modificar una gran cantidad de código para hacer ese cambio.

+2

Windows agregó soporte para UTF-16 al hacer una versión duplicada de toda la API de Windows. Agregar soporte para UTF-8 hubiera sido mucho más simple. – dan04

+2

En realidad, Windows agregó soporte para 'UCS-2' al hacer eso, y luego fue" 640k de nuevo "cuando resultó que 16 bits no eran suficientes ... ;-) –

+5

@ dan04 Hubiera sido difícil escriba NT usando UTF-8 en lugar de UCS2 dado que NT es anterior a UTF-8. Eso habría requerido una previsión extraordinaria. –

2

Creo que es principalmente la compatibilidad hacia atrás que ofrece UTF8 con ASCII.

Para una respuesta a la pregunta 'peligros', debe especificar lo que quiere decir 'interactuando'. ¿Te refieres a interactuar con el shell, con libc, o con el kernel propiamente dicho?

0

Sí, es por razones de compatibilidad. UTF-8 es comprable al revés con ASCII. Linux/Unix estaba basado en ASCII, por lo que acaba de hacer/tiene sentido.

0

Pensé que el ASCII de 7 bits estaba bien.

serio, Unicode es relativamente nuevo en el esquema de las cosas, y UTF-8 es compatible con ASCII y utiliza menos espacio (medio) para los archivos típicos ya que utiliza 1 a 4 bytes por código de punto (carácter), mientras que UTF-16 usos 2 o 4 bytes por punto de código (personaje).

UTF-16 es preferible para el uso del programa interno debido a los anchos más simples. Su predecesor UCS-2 tenía exactamente 2 bytes por cada punto de código.

+1

No veo que los anchos sean mucho más simples. Aún tienes que escanear toda la cadena. Si se trata de mucho texto CJK, entonces UTF-16 puede ser más compacto que UTF-8 y puede valer la pena usarlo por esa razón, de lo contrario me quedaría con UTF-8 en todas partes. –

+4

A la derecha, UTF-16 ha perdido las grandes ventajas que tenía UCS-2. –

+1

(UTF-16 ha perdido las grandes ventajas que tenía UCS-2) ... pero ganó la gama completa de caracteres Unicode. – tzot

2

Unixes modernos usan UTF-8, pero esto no siempre fue así. En RHEL2, que tiene solo unos pocos años, el valor predeterminado es

$ locale 
LANG=C 
LC_CTYPE="C" 
LC_NUMERIC="C" 
LC_TIME="C" 
LC_COLLATE="C" 
LC_MONETARY="C" 
LC_MESSAGES="C" 
LC_PAPER="C" 
LC_NAME="C" 
LC_ADDRESS="C" 
LC_TELEPHONE="C" 
LC_MEASUREMENT="C" 
LC_IDENTIFICATION="C" 
LC_ALL=
Se espera que la configuración regional de C/POSIX sea una codificación compatible con ASCII de 7 bits.

Sin embargo, como declaró Jonathan Leffler, cualquier codificación que permita bytes NUL dentro de una secuencia de caracteres no es viable en Unix, ya que las API del sistema son ignorantes de la configuración regional; se supone que todas las cadenas son secuencias de bytes terminadas por \ 0.

+0

No tiene que ser una codificación compatible con ASCII, pero el estándar POSIX dice "Un byte con todos los bits cero se interpretará como el carácter nulo independiente del estado de cambio. Por lo tanto, nunca se producirá un byte con todos los bits cero el segundo o subsiguientes bytes de un personaje ". Esto significa que UTF-16 y UTF-32 no están permitidos, pero UTF-8 sí lo está. – dan04

0

Creo que es porque los programas que esperan entrada ASCII no podrán manejar codificaciones como UTF-16. Para la mayoría de los caracteres (en el rango 0-255), esos programas verán el byte alto como un carácter NUL/0, que se usa en muchos idiomas y sistemas para marcar el final de una cadena. Esto no sucede en UTF-8, que fue diseñado para evitar NUL incrustados y ser agnóstico de orden de bytes.

8

Como menciona jonathan-leffler, el problema principal es el carácter nulo ASCII. C tradicionalmente espera que una cadena sea terminada nula. Por lo tanto, las funciones estándar de cadena C se obstruirán con cualquier carácter UTF-16 que contenga un byte equivalente a un ASCII nulo (0x00). Si bien es cierto que puede programar con soporte para caracteres anchos, UTF-16 no es una codificación externa adecuada de Unicode en filenames, text files, environment variables.

Además, UTF-16 y UTF-32 tienen orientaciones big endian y little endian. Para tratar con esto, necesitará metadatos externos como un tipo MIME, o un Byte Orientation Mark.Se observa,

Cuando se utiliza UTF-8 de forma transparente en entornos de 8 bits, el uso de una lista de materiales interferirá con cualquier formato de archivo de protocolo o que espera caracteres específicos ASCII al principio, tales como el uso de "#!" de en el inicio de scripts de shell de Unix.

El predecesor a UTF-16, que fue llamado UCS-2 y no apoyó pares suplentes, tenían el same issues. UCS-2 debe ser evitado.

+0

Si se debe evitar UCS-2, entonces también se debe evitar MS Windows :) – tzot

+1

Aparentemente, Windows admite pares de sustitución, a diferencia de UCS2. – MSalters

1

Creo que cuando Microsoft comenzó a utilizar una codificación de dos bytes, no se asignaron caracteres por encima de 0xffff, por lo que usar una codificación de dos bytes significaba que nadie tenía que preocuparse de que los caracteres fueran de diferentes longitudes.

Ahora que hay caracteres fuera de este rango, entonces tendrá que tratar con caracteres de diferentes longitudes de todos modos, ¿por qué alguien usaría UTF-16? Sospecho que Microsoft tomaría una decisión diferente si estuviera presentando su soporte Unicode hoy.

+0

Era más que UTF-8 no existía cuando se diseñó NT. –

Cuestiones relacionadas