iconv generando UTF-16 con BOM

11

Inspirado por esta pregunta , ¿puedo usar el iconvcomando para generar una salida UTF-16 con una lista de materiales y con especificidad?

El iconvcomando convierte el texto de una codificación a otra.

Por ejemplo:

echo hello | iconv -f ascii -t utf-16

genera una representación UTF-16 de "hello\n".

Los archivos UTF-16 a menudo, pero no siempre, comienzan con una marca de orden de bytes (BOM), que es una codificación de 2 bytes del carácter Unicode U+FEFF. Puede determinar la endianness de un archivo UTF-16 con BOM comprobando si los dos primeros bytes son FE FFo FF FE.

El iconvcomando tiene varias opciones para generar la salida UTF-16:

$ iconv --list | grep -i utf-16
UTF-16//
UTF-16BE//
UTF-16LE//

Este comando:

echo hello | iconv -f ascii -t utf-16be

genera UTF-16 big-endian sin BOM ; parece suponer que si especificó el endianness, no necesita indicarlo en la salida. Del mismo modo, utf-16legenera little-endian UTF-16 sin BOM.

Esta:

echo hello | iconv -f ascii -t utf-16

genera (en mi sistema Ubuntu x86) little-endian UTF-16 con una BOM, pero he visto un informe de un comando similar que genera UTF-16 big-endian con una BOM, incluso en un sistema little-endian.

Siempre puedo usar utf-16beo utf-16ley anteponer la lista de materiales manualmente, pero estoy buscando una solución que solo use el iconvcomando.

Otra solución, si sabes lo que -t utf-16genera endianness , es:

echo hello | iconv -f ascii -t utf-16 | dd conv=swab 2>/dev/null

Lo que me gustaría usar es algo como:

iconv -f ascii -t utf-16bebom # big-endian with BOM
iconv -f ascii -t utf-16lebom # little-endian with BOM

Pero iconvno es compatible con eso.

EDITAR:

¿Alguien con acceso a un sistema Mac OSX x86 puede publicar un comentario que muestre el resultado (copiar y pegar) del siguiente comando?

echo hello | iconv -f ascii -t utf-16 | od -x
Keith Thompson
fuente
1
Una lista de materiales reduce la portabilidad de los datos, pero puede agregarlos de esta manera
RedGrittyBrick
@RedGrittyBrick: ¿Cómo reduce la portabilidad (específicamente para UtF-16)? Sé que puedo generar la lista de materiales ezplicitly; Estoy buscando una manera de hacerlo simplemente usando iconv, y me pregunto por qué -t utf-16parece dejar el endianness sin especificar.
Keith Thompson
Supongo que iconv asume el orden de bytes de la plataforma actual si no lo especifica explícitamente. En algunas plataformas que no sean Windows, algunas herramientas de procesamiento de texto no esperan listas de materiales y, por lo tanto, hacen lo incorrecto. Un ejemplo podría ser al concatenar archivos de texto o al usar plantillas basadas en archivos para construir contenido. "Para los conjuntos de caracteres registrados de la IANA UTF-16BE y UTF-16LE, no se debe usar una marca de orden de bytes porque los nombres de estos conjuntos de caracteres ya determinan el orden de bytes"
RedGrittyBrick
Esta pregunta muestra iconv -f UTF-8 -t UTF-16, ejecutar en un sistema little-endian (MacOS), generando UTF-16 big-endian con una lista de materiales, lo que parece muy extraño.
Keith Thompson

Respuestas:

9

No , si se especifica el orden de los bytes, iconvno inserte una lista de materiales.

Esto es del Consorcio Unicode

P: ¿Cómo debo tratar con las listas de materiales?

R: Aquí hay algunas pautas a seguir:

  1. Un protocolo particular (por ejemplo, las convenciones de Microsoft para archivos .txt) puede requerir el uso de la lista de materiales en ciertos flujos de datos Unicode, como archivos. Cuando necesite cumplir con dicho protocolo, use una lista de materiales.
  2. Algunos protocolos permiten listas de materiales opcionales en el caso de texto sin etiquetar. En esos casos
    • Cuando se sabe que una secuencia de datos de texto es texto sin formato, pero de codificación desconocida, BOM se puede usar como firma. Si no hay una lista de materiales, la codificación podría ser cualquier cosa.
    • Cuando se sabe que una secuencia de datos de texto es texto Unicode simple (pero no qué endian), entonces se puede usar BOM como firma. Si no hay una lista de materiales, el texto debe interpretarse como big-endian.
  3. Algunos protocolos orientados a bytes esperan caracteres ASCII al comienzo de un archivo. Si se usa UTF-8 con estos protocolos, se debe evitar el uso de la lista de materiales como codificación de firma de formulario.
  4. Cuando se conoce el tipo preciso de flujo de datos (por ejemplo, Unicode big-endian o Unicode little-endian), no se debe utilizar la lista de materiales. En particular, siempre que se declare que un flujo de datos es UTF-16BE, UTF-16LE, UTF-32BE o UTF-32LE, no se debe utilizar una lista de materiales .

(mi énfasis)

Espero que iconvintente ser fiel a la última de estas pautas.


Actualizar.

Una digresión

En mi opinión:

  1. Una opción para especificar una lista de materiales sería una característica adicional útil para iconv.

  2. Un archivo UTF-16LE sin una lista de materiales se puede utilizar en Windows, aunque a veces con un esfuerzo adicional. Por ejemplo, el diálogo Abrir archivo del Bloc de notas le permite seleccionar "Unicode", que es el nombre de Microsoft para "UTF-16LE" y (como era de esperar) parece funcionar en archivos sin una lista de materiales.

  3. Puedo abrir un archivo de prueba UTF-16LE (sin BOM) o un archivo de prueba UTF-8 (sin BOM) en Windows Notepad (XP) de la manera habitual, por ejemplo, haciendo doble clic en el nombre del archivo en el explorador. Eso me parece utilizable. Soy consciente de que a veces Windows adivinará la codificación incorrectamente, en cuyo caso debe indicarle al Bloc de notas la codificación al abrir el archivo. Este inconveniente significa que es preferible incluir una lista de materiales para los archivos de texto destinados a Windows.

  4. Si una aplicación específica no funciona con otra cosa que no sea un archivo UTF-16LE con BOM, entonces estaría de acuerdo en que un archivo UTF-16LE sin BOM no se puede usar para esa aplicación específica.

  5. Sospecho que si puede hacer que todo funcione con UTF-8 (sin BOM), esa es la mejor solución a largo plazo.

Sin embargo, la respuesta a la pregunta " ¿puedo usar el comando iconv para generar una salida UTF-16 con una lista de materiales y con una especificidad específica " es actualmente " No ".

RedGrittyBrick
fuente
1
¿Y qué hay de la primera directriz, A.1? Si quiero generar un archivo de texto Unicode que se pueda usar en un sistema Windows x86, debería ser un archivo UTF16 little endian con una lista de materiales .
Keith Thompson
@KeithThompson: Sistemas debe aceptar tanto UTF16LE y UTF16BE. Al menos el Bloc de notas de Windows acepta ambos, cuando se trata de .txt's, siempre que el archivo tenga una lista de materiales.
user1686
@KeithThompson: estoy de acuerdo en que la directriz 1 debe tener prioridad, sin embargo, iconv no le proporciona una forma de especificar una lista de materiales. La respuesta a su pregunta original es simplemente "No".
RedGrittyBrick
¡No es la respuesta que esperaba, sino una respuesta, y completa!
Keith Thompson el
2
Esta respuesta me ayudó, me ayudó a saber por qué estaba jodido. El programa estándar de Windows para exportar / importar desde el registro, C:\Windows\System32\reg.exeexporta UTF-16 LE CON BOM y solo leerá UTF-16 LE CON BOM - no leerá UTF-16 LE sin BOM y no leerá UTF-16 BE con BOM - en otras palabras, exige la lista de materiales al leer, ¡pero es mejor que sea la correcta! (Afortunadamente, se lee UTF-8.)
davidbak