iconv générant UTF-16 avec BOM

11

Inspiré par cette question , puis-je utiliser la iconvcommande pour générer une sortie UTF-16 avec une nomenclature et avec une endianité spécifiée?

La iconvcommande convertit le texte d'un encodage en un autre.

Par exemple:

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

génère une représentation UTF-16 de "hello\n".

Les fichiers UTF-16 commencent souvent, mais pas toujours, par une marque d'ordre des octets (BOM), qui est un codage sur 2 octets du caractère Unicode U+FEFF. Vous pouvez déterminer l'endianité d'un fichier UTF-16 avec BOM en vérifiant si les deux premiers octets sont FE FFou FF FE.

La iconvcommande a plusieurs options pour générer une sortie UTF-16:

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

Cette commande:

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

génère UTF-16 big-endian sans BOM ; il semble supposer que si vous avez spécifié l'endianité, vous n'avez pas besoin de l'indiquer dans la sortie. De même, utf-16legénère un UTF-16 peu endian sans BOM.

Ce:

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

génère (sur mon système Ubuntu x86) UTF-16 little-endian avec une nomenclature - mais j'ai vu un rapport d'une commande similaire générant UTF-16 big-endian avec une nomenclature, même sur un système little-endian.

Je peux toujours utiliser utf-16beou utf-16leet ajouter la nomenclature manuellement, mais je recherche une solution qui utilise simplement la iconvcommande.

Une autre solution de contournement, si vous savez ce que l'endianité -t utf-16génère, est:

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

Ce que je veux est quelque chose comme à l' utilisation:

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

mais iconvne supporte pas cela.

ÉDITER :

Une personne ayant accès à un système Mac OSX x86 peut-elle publier un commentaire montrant la sortie (copiée-collée) de la commande suivante?

echo hello | iconv -f ascii -t utf-16 | od -x
Keith Thompson
la source
1
Une nomenclature réduit la portabilité des données, mais vous pouvez l' ajouter de cette façon
RedGrittyBrick
@RedGrittyBrick: Comment cela réduit-il la portabilité (spécifiquement pour UtF-16)? Je sais que je peux générer la nomenclature avec efficacité; Je cherche un moyen de le faire en utilisant simplement iconv- et je me demande pourquoi -t utf-16semble ne pas spécifier l'endianité.
Keith Thompson
Je suppose que iconv suppose l'ordre des octets de la plate-forme actuelle si vous ne le spécifiez pas explicitement. Sur certaines plates-formes autres que Windows, certains outils de traitement de texte ne s'attendent pas à des nomenclatures et font donc la mauvaise chose. Un exemple peut être lors de la concaténation de fichiers texte ou de l'utilisation de modèles basés sur des fichiers pour construire du contenu. "Pour les jeux de caractères enregistrés IANA UTF-16BE et UTF-16LE, une marque d'ordre d'octets ne doit pas être utilisée car les noms de ces jeux de caractères déterminent déjà l'ordre des octets"
RedGrittyBrick
Cette question montre iconv -f UTF-8 -t UTF-16, exécutée sur un système little-endian (MacOS), générant du big-endian UTF-16 avec une nomenclature, ce qui semble très étrange.
Keith Thompson

Réponses:

9

Non , si vous spécifiez l'ordre des octets, iconvn'insère pas de nomenclature.

C'est du Consortium Unicode

Q: Comment dois-je traiter les nomenclatures?

R: Voici quelques directives à suivre:

  1. Un protocole particulier (par exemple les conventions Microsoft pour les fichiers .txt) peut nécessiter l'utilisation de la nomenclature sur certains flux de données Unicode, tels que les fichiers. Lorsque vous devez vous conformer à un tel protocole, utilisez une nomenclature.
  2. Certains protocoles autorisent les nomenclatures facultatives dans le cas de texte non balisé. Dans ces cas,
    • Lorsqu'un flux de données texte est connu pour être du texte brut, mais d'un codage inconnu, la nomenclature peut être utilisée comme signature. S'il n'y a pas de nomenclature, le codage pourrait être n'importe quoi.
    • Lorsqu'un flux de données texte est connu pour être du texte Unicode simple (mais pas quel endian), la nomenclature peut être utilisée comme signature. S'il n'y a pas de nomenclature, le texte doit être interprété comme big-endian.
  3. Certains protocoles orientés octets attendent des caractères ASCII au début d'un fichier. Si UTF-8 est utilisé avec ces protocoles, l'utilisation de la nomenclature comme signature de formulaire de codage doit être évitée.
  4. Lorsque le type précis du flux de données est connu (par exemple, big-endian Unicode ou little-endian Unicode), la nomenclature ne doit pas être utilisée. En particulier, chaque fois qu'un flux de données est déclaré UTF-16BE, UTF-16LE, UTF-32BE ou UTF-32LE, une nomenclature ne doit pas être utilisée.

(mon accent)

Je m'attends à iconvessayer d'être fidèle à la dernière de ces lignes directrices.


Mettre à jour.

Une digression

À mon avis:

  1. Une option pour spécifier une nomenclature serait certainement une fonctionnalité supplémentaire utile pour iconv.

  2. Un fichier UTF-16LE sans nomenclature est utilisable sous Windows, bien qu'avec des efforts supplémentaires parfois. Par exemple, la boîte de dialogue d'ouverture de fichier du Bloc-notes vous permet de sélectionner "Unicode" qui est le nom de Microsoft pour "UTF-16LE" et (sans surprise) semble fonctionner sur des fichiers sans nomenclature.

  3. Je peux ouvrir un fichier de test UTF-16LE (sans nomenclature) ou un fichier de test UTF-8 (sans nomenclature) dans le Bloc-notes Windows (XP) de la manière habituelle, par exemple en double-cliquant sur le nom du fichier dans l'explorateur. Cela me semble utilisable. Je suis conscient que parfois Windows devinera l'encodage de manière incorrecte - Dans ce cas, vous devez indiquer l'encodage au Bloc-notes lors de l'ouverture du fichier. Cet inconvénient signifie que l'inclusion d'une nomenclature est préférable pour les fichiers texte destinés à être utilisés sous Windows.

  4. Si une application spécifique ne fonctionne pas avec autre chose qu'un fichier UTF-16LE avec BOM, alors je conviens qu'un fichier UTF-16LE sans BOM n'est pas utilisable pour cette application spécifique.

  5. Je soupçonne que si vous pouvez tout faire fonctionner avec UTF-8 (sans BOM), c'est la meilleure solution à long terme.

Cependant, la réponse à la question " puis-je utiliser la commande iconv pour générer une sortie UTF-16 avec une nomenclature et avec une endianité spécifiée " est actuellement " Non ".

RedGrittyBrick
la source
1
Et qu'en est-il de la première ligne directrice, A.1? Si je souhaite générer un fichier texte Unicode utilisable sur un système Windows x86, il doit s'agir d'un fichier UTF16 petit-boutien avec une nomenclature .
Keith Thompson
@KeithThompson: Les systèmes doivent accepter à la fois UTF16LE et UTF16BE. Au moins, le Bloc-notes Windows accepte les deux, quand il s'agit de .txt- tant que le fichier a une nomenclature.
user1686
@KeithThompson: Je suis d'accord que la directive 1 devrait être prioritaire, mais iconv ne vous permet pas de spécifier une nomenclature. La réponse à votre question d'origine est simplement "Non".
RedGrittyBrick
Pas la réponse que j'espérais, mais une réponse, et une réponse complète!
Keith Thompson
2
Cette réponse m'a aidé - m'a aidé à comprendre pourquoi j'étais foutu. Le programme Windows standard pour exporter / importer à partir du registre, C:\Windows\System32\reg.exeexporte UTF-16 LE AVEC BOM et ne lira que UTF-16 LE AVEC BOM - ne lira pas UTF-16 LE sans BOM et ne lira pas UTF-16 BE avec BOM - en d'autres termes, il exige la nomenclature lors de la lecture, mais il vaut mieux être le bon! (Heureusement, il lit UTF-8.)
davidbak