web-dev-qa-db-fra.com

Comment puis-je tester l'encodage d'un fichier texte ... Est-il valide et de quoi s'agit-il?

J'ai plusieurs .htm fichiers qui s'ouvrent dans Gedit sans aucun avertissement/erreur, mais quand j'ouvre ces mêmes fichiers dans Jedit, cela m'avertit d'un encodage UTF-8 invalide ...

La balise Meta HTML indique "charset = ISO-8859-1". Jedit permet une liste des encodages de secours et une liste des auto-détecteurs d'encodage (actuellement "BOM XML-PI"), mon problème immédiat a donc été résolu. Mais cela m'a fait réfléchir: et si les métadonnées n'étaient pas là?

Lorsque les informations d'encodage ne sont tout simplement pas disponibles, existe-t-il un programme CLI qui peut faire une "meilleure estimation" des encodages qui peuvent s'appliquer?

Et, bien que ce soit un problème légèrement différent; existe-t-il un programme CLI qui teste la validité d'un codage connu ?

55
Peter.O

La commande file fait des "meilleures suppositions" sur l'encodage. Utilisez le -i paramètre pour forcer file à imprimer des informations sur l'encodage.

Manifestation:

$ file -i *
umlaut-iso88591.txt: text/plain; charset=iso-8859-1
umlaut-utf16.txt:    text/plain; charset=utf-16le
umlaut-utf8.txt:     text/plain; charset=utf-8

Voici comment j'ai créé les fichiers:

$ echo ä > umlaut-utf8.txt 

De nos jours, tout est utf-8. Mais convaincez-vous:

$ hexdump -C umlaut-utf8.txt 
00000000  c3 a4 0a                                          |...|
00000003

Comparer avec https://en.wikipedia.org/wiki/Ä#Computer_encoding

Convertir vers les autres encodages:

$ iconv -f utf8 -t iso88591 umlaut-utf8.txt > umlaut-iso88591.txt 
$ iconv -f utf8 -t utf16 umlaut-utf8.txt > umlaut-utf16.txt 

Vérifiez le vidage hexadécimal:

$ hexdump -C umlaut-iso88591.txt 
00000000  e4 0a                                             |..|
00000002
$ hexdump -C umlaut-utf16.txt 
00000000  ff fe e4 00 0a 00                                 |......|
00000006

Créez quelque chose de "non valide" en mélangeant les trois:

$ cat umlaut-iso88591.txt umlaut-utf8.txt umlaut-utf16.txt > umlaut-mixed.txt 

Ce que file dit:

$ file -i *
umlaut-iso88591.txt: text/plain; charset=iso-8859-1
umlaut-mixed.txt:    application/octet-stream; charset=binary
umlaut-utf16.txt:    text/plain; charset=utf-16le
umlaut-utf8.txt:     text/plain; charset=utf-8

sans pour autant -i:

$ file *
umlaut-iso88591.txt: ISO-8859 text
umlaut-mixed.txt:    data
umlaut-utf16.txt:    Little-endian UTF-16 Unicode text, with no line terminators
umlaut-utf8.txt:     UTF-8 Unicode text

La commande file n'a aucune idée de "valide" ou "invalide". Il ne voit que quelques octets et essaie de deviner quel pourrait être l'encodage. En tant qu'êtres humains, nous pourrions être en mesure de reconnaître qu'un fichier est un fichier texte avec quelques trémas dans un "mauvais" encodage. Mais en tant qu'ordinateur, il aurait besoin d'une sorte d'intelligence artificielle.

On pourrait soutenir que l'heuristique de file est une sorte d'intelligence artificielle. Pourtant, même si elle l'est, elle est très limitée.

Voici plus d'informations sur la commande file: http://www.linfo.org/file_command.html

70
lesmana

Il n'est pas toujours possible de savoir avec certitude quel est l'encodage d'un fichier texte. Par exemple, la séquence d'octets \303\275 (c3 bd en hexadécimal) pourrait être ý en UTF-8, ou ý en latin1, ou Ă˝ en latin2, ou en BIG-5, etc.

Certains encodages ont des séquences d'octets invalides, il est donc possible de les exclure à coup sûr. Cela est vrai en particulier de l'UTF-8; la plupart des textes dans la plupart des encodages 8 bits ne sont pas des UTF-8 valides. Vous pouvez tester l'UTF-8 valide avec isutf8 de moreutils ou avec iconv -f utf-8 -t utf-8 >/dev/null, entre autres.

Il existe des outils qui tentent de deviner l'encodage d'un fichier texte. Ils peuvent faire des erreurs, mais ils fonctionnent souvent dans la pratique tant que vous n'essayez pas délibérément de les tromper.

  • file
  • Perl Encode::Guess (partie de la distribution standard) essaie les encodages successifs sur une chaîne d'octets et retourne le premier encodage dans lequel la chaîne est du texte valide.
  • Enca est un devineur et un convertisseur d'encodage. Vous pouvez lui donner un nom de langue et un texte que vous supposez être dans cette langue (les langues prises en charge sont principalement des langues d'Europe de l'Est), et il essaie de deviner l'encodage.

S'il existe des métadonnées (HTML/XML charset=, TeX \inputenc, emacs -*-coding-*-,…) Dans le fichier, les éditeurs avancés comme Emacs ou Vim sont souvent capables d'analyser ces métadonnées. Ce n'est pas facile à automatiser depuis la ligne de commande.

Même si vous déposez -i vous donne inconnu

Vous pouvez utiliser cette commande php qui peut deviner le jeu de caractères comme ci-dessous:

En php, vous pouvez vérifier comme ci-dessous:

Spécification explicite de la liste d'encodage:

php -r "echo 'probably : ' . mb_detect_encoding(file_get_contents('myfile.txt'), 'UTF-8, ASCII, JIS, EUC-JP, SJIS, iso-8859-1') . PHP_EOL;"

Plus précis " mb_list_encodings ":

php -r "echo 'probably : ' . mb_detect_encoding(file_get_contents('myfile.txt'), mb_list_encodings()) . PHP_EOL;"

Ici, dans le premier exemple, vous pouvez voir que j'ai mis une liste d'encodages (détecter l'ordre des listes) qui pourraient correspondre. Pour avoir un résultat plus précis, vous pouvez utiliser tous les encodages possibles via: mb_list_encodings ()

Remarque: les fonctions mb_ * nécessitent php-mbstring

apt-get install php-mbstring 

Voir la réponse: https://stackoverflow.com/a/57010566/3382822

1
Mohamed23gharbi