J'essaie d'identifier un personnage étrange que j'ai trouvé dans un fichier avec lequel je travaille:
$ cat file
�
$ od file
0000000 005353
0000002
$ od -c file
0000000 353 \n
0000002
$ od -x file
0000000 0aeb
0000002
Le fichier utilise le codage ISO-8859 et ne peut pas être converti en UTF-8:
$ iconv -f ISO-8859 -t UTF-8 file
iconv: conversion from `ISO-8859' is not supported
Try `iconv --help' or `iconv --usage' for more information.
$ iconv -t UTF-8 file
iconv: illegal input sequence at position 0
$ file file
file: ISO-8859 text
Ma principale question est de savoir comment puis-je interpréter la sortie d' od
ici? J'essaie d'utiliser cette page qui me permet de traduire entre différentes représentations de caractères, mais elle me dit qu'en 005353
tant que "point de code hexadécimal" 卓
ce qui ne semble pas correct et en 0aeb
tant que "point de code hexadécimal" est ૫
ce qui, encore une fois, semble incorrect .
Alors, comment puis-je utiliser l'une des trois options ( 355
, 005353
ou 0aeb
) pour savoir quel personnage ils sont censés représenter?
Et oui, j'ai essayé avec les outils Unicode mais il ne semble pas non plus être un caractère UTF valide:
$ uniprops $(cat file)
U+FFFD ‹�› \N{REPLACEMENT CHARACTER}
\pS \p{So}
All Any Assigned Common Zyyy So S Gr_Base Grapheme_Base Graph X_POSIX_Graph
GrBase Other_Symbol Print X_POSIX_Print Symbol Specials Unicode
si je comprends la description du caractère Unicode U + FFFD, ce n'est pas du tout un vrai caractère mais un espace réservé pour un caractère corrompu. Ce qui est logique puisque le fichier n'est pas réellement encodé en UTF-8.
la source
iconv
plaint parce que vous n'avez pas spécifié le jeu de caractères source, il utilise donc votre valeur par défaut qui est probablement UTF-8.)ë
c'est ce que je vois quand les données sont utilisées sur un autre programme! Mais comment puis-je le savoir? N'est-ce pas quelque part dans les données que je fournis? Comment avez-vous trouvé? Oh, j'avais essayéiconv
avec-f ISO-8859
mais il se plaignait de l'conversion from
ISO-8859 «n'est pas pris en charge».eb
et ignorer l'0x
indicateur hexadécimal ou quoi que ce soit. Mon ignorance de ce genre de chose est profonde. Pourriez-vous poster une réponse expliquant que @StephenKitt?iconv
auriez réussi; et / ou vous auriez pu le rechercher par exemple sur Wikipédia. Pour cet encodage très spécifique, fileformat.info/info/unicode/char/00eb/index.htm fonctionne également (Unicode est équivalent à ISO-8859-1 dans la gamme 128-255, bien que bien sûr aucun encodage UTF ne soit compatible avec lui ).Réponses:
Votre fichier contient deux octets, EB et 0A en hexadécimal. Il est probable que le fichier utilise un jeu de caractères avec un octet par caractère, tel que ISO-8859-1 ; dans ce jeu de caractères, EB est ë:
Les autres candidats seraient δ dans la page de code 437 , Ù dans la page de code 850 ...
od -x
La sortie de confuse dans ce cas en raison de l'endianité; une meilleure option est celle-t x1
qui utilise des octets simples:od -x
les cartesod -t x2
auxquelles lit deux octets à la fois, et sur les systèmes little-endian sortent les octets dans l'ordre inverse.Lorsque vous rencontrez un fichier comme celui-ci, qui n'est pas UTF-8 valide (ou n'a aucun sens lorsqu'il est interprété comme un fichier UTF-8), il n'y a aucun moyen infaillible de déterminer automatiquement son encodage (et son jeu de caractères). Le contexte peut aider: s'il s'agit d'un fichier produit sur un PC occidental au cours des deux dernières décennies, il y a de fortes chances qu'il soit codé en ISO-8859-1, -15 (la variante Euro) ou Windows-1252; s'il est plus ancien que cela, les CP-437 et CP-850 sont probablement des candidats. Les fichiers des systèmes d'Europe de l'Est, des systèmes russes ou des systèmes asiatiques utiliseraient différents jeux de caractères que je ne connais pas beaucoup. Ensuite, il y a EBCDIC ... listera
iconv -l
tous les jeux de caractères connusiconv
, et vous pouvez procéder par essais et erreurs à partir de là.(À un moment donné, je connaissais par cœur la plupart des CP-437 et ATASCII, c'était l'époque.)
la source
ë
est décrit comme00EB
et234
. Quels sont ces extra00
? Et pourquoi n'est-ce pas ce355
que j'attendais de laod
sortie? J'essaie d'obtenir une réponse plus générale sur la façon dont je peux utiliser laod
sortie pour identifier le personnage. Pourriez-vous peut-être expliquer quelque chose sur l'interprétation des codes hexadécimaux et / ou quelles informations sont nécessaires pour être en mesure d'identifier un caractère inconnu (encodage et autre)?353
. Le 353 est donc une représentation octale, pas décimale. Argh.od
signifie octal ;-).�
(U + FFFD) serait affiché par l'émulateur de terminal en remplacement de cet octet 0xeb qui ne forme pas un caractère valide en UTF-8. On ne sait pas pourquoiuniprops $(cat file)
(guillemets manquants btw) signalerait cela (je ne sais pas pour cetteuniprops
commande).unicode "$(cat file)"
sur Debian produitSequence '\xeb' is not valid in charset 'UTF-8'
comme je m'y attendais.Notez que
od
c'est court pour le vidage octal ,005353
les deux octets comme mot octal,od -x
sont0aeb
en hexadécimal comme mot, et le contenu réel de votre fichier est les deux octetseb
et0a
en hexadécimal, dans cet ordre.Donc, les deux
005353
et0aeb
ne peuvent pas simplement être interprétés comme «point de code hexadécimal».0a
est un saut de ligne (LF) eteb
dépend de votre encodage.file
est juste de deviner l'encodage, ça pourrait être n'importe quoi. Sans aucune autre information sur l'origine du fichier, etc., il sera difficile de le savoir.la source
od -c
car cela produit une sortie que je peux comprendre. Comment aurais-je pu utiliser le355
qui produit pour identifier le personnage? Et pourquoi imprime-t-il0aeb
au lieu deeb0a
si0a
est la nouvelle ligne?Il est impossible de deviner avec 100% de précision le jeu de caractères des fichiers texte.
Des outils comme chardet , firefox , file -i quand aucune information explicite de jeu de caractères n'est définie (par exemple, si un HTML contient un méta jeu de caractères = ... dans la tête, les choses sont plus faciles) essaieront d'utiliser des heuristiques qui ne sont pas si mauvaises si le texte est assez gros.
Dans ce qui suit, je démontre la détection de charset avec
chardet
(pip install chardet
/apt-get install python-chardet
si nécessaire).Après avoir un bon candidat de jeu de caractères, nous pouvons utiliser
iconv
,recode
ou similaire, pour changer le fichier de caractères en votre jeu de caractères "actif" (dans mon cas utf-8) et voir s'il a bien deviné ...Certains jeux de caractères (comme iso-8859-3, iso-8859-1) ont de nombreux caractères en commun - parfois, il n'est pas facile de voir si nous avons trouvé le jeu de caractères parfait ...
Il est donc très important d'avoir des métadonnées associées au texte pertinent (par exemple XML).
la source
iconv -f ... -t utf-8
vous montrera les caractères?iso-8850-1
. iso-8859 est un standart iso qui inclut plusieurs définitions de chaset. Essayezfile -i ...
iconv -f ISO-8859-1 -t UTF-8 file
Si j'obtiens un fichier qui contient, par exemple, le mot Begrung, je peux en déduire que Begrüßung pourrait être voulu. Je le convertis donc par tous les encodindgs connus et regarde, s'il y en a un, qui le convertit correctement.
Habituellement, il existe plusieurs encodages qui semblent correspondre.
Pour les fichiers plus longs, vous pouvez couper un extrait au lieu de convertir des centaines de pages.
Donc je l'appellerais
et les tests de script, que ce soit en les convertissant avec les encodages connus, lesquels produisent "Begrüßung".
Pour trouver de tels personnages, moins est généralement utile, car les personnages funky se distinguent souvent. Du contexte, le bon mot à rechercher peut généralement être déduit. Mais nous ne voulons pas vérifier avec un hexeditor, de quel octet il s'agit, puis visiter des tables infinies d'encodages, pour trouver notre délinquant. :)
la source