Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

lire un fichier d'encodage inconnu

8 réponses
Avatar
mpg
Bonjour,

Mettons que je souhaite lire un fichier dont l'encodage m'est a priori
inconnu (mais quand même une extension d'ascii, faut pas pousser), jusqu'à
y reconnaître un chaîne ne contenant que des caractères ascii.

Concrêtement, on considère un source LaTeX auquel je veux faire subir les
pires avanies, mais auparavant j'aimerais récupérer son encodage en
reconnaissant la déclaration \usepackage[<encoding>]{inputenc} qui ne
manque pas de s'y trouver (hum, hum). Le problème est qu'avant cette
déclaration peuvent se trouver des caractères arbitraires dont je ne
connais pas l'encodage, donc des suites d'octets presque arbitraires.

Pour l'instant, je tourne le problème en commençant par ouvrir le fichier
comme si c'était du latin1, jusqu'à tomber sur la déclaration d'encodage :
là je le ferme, puis le rouvre avec le bon encodage.

Est-ce « la bonne » ou au moins une bonne manière de procéder ? En fait, je
ne sais pas trop ce qui risque de se passer si le fichier contient des
octets bizarres, c'est-à-dire entre 0x00 et 0x1F ou entre 0x80 et 0x9F, ou
0x7F, qui sont soit des caractères de contrôle soit des slots non attribués
en latin1.

Merci,
Manuel.

8 réponses

Avatar
Nicolas George
mpg wrote in message <gi1cqe$2mi7$:
Le problème est qu'avant cette
déclaration peuvent se trouver des caractères arbitraires dont je ne
connais pas l'encodage, donc des suites d'octets presque arbitraires.



Si l'encodage est compatible avec ASCII, la situation est infiniment moins
grave que ce que tu dis.

Pour l'instant, je tourne le problème en commençant par ouvrir le fichier
comme si c'était du latin1, jusqu'à tomber sur la déclaration d'encodage :
là je le ferme, puis le rouvre avec le bon encodage.



Je dirais : lire le fichier comme une suite d'octets interprété comme ASCII
étendu, détecter l'encodage (c'est une expression rationnelle sur de
l'ASCII, ça marchera), et utiliser Encode::decode pour l'appliquer.
Avatar
Paul Gaborit
À (at) Sat, 13 Dec 2008 23:26:22 +0100,
mpg écrivait (wrote):
Mettons que je souhaite lire un fichier dont l'encodage m'est a priori
inconnu (mais quand même une extension d'ascii, faut pas pousser), jusqu'à
y reconnaître un chaîne ne contenant que des caractères ascii.

Concrêtement, on considère un source LaTeX auquel je veux faire subir les
pires avanies, mais auparavant j'aimerais récupérer son encodage en
reconnaissant la déclaration usepackage[<encoding>]{inputenc} qui ne
manque pas de s'y trouver (hum, hum). Le problème est qu'avant cette
déclaration peuvent se trouver des caractères arbitraires dont je ne
connais pas l'encodage, donc des suites d'octets presque arbitraires.

Pour l'instant, je tourne le problème en commençant par ouvrir le fichier
comme si c'était du latin1, jusqu'à tomber sur la déclaration d'encodage :
là je le ferme, puis le rouvre avec le bon encodage.



C'est une bonne solution. Tu peux même te passer de déclaration
d'encodage initialement puisque tu sais que c'est de l'ASCII.

Est-ce « la bonne » ou au moins une bonne manière de procéder ? En fait, je
ne sais pas trop ce qui risque de se passer si le fichier contient des
octets bizarres, c'est-à-dire entre 0x00 et 0x1F ou entre 0x80 et 0x9F, ou
0x7F, qui sont soit des caractères de contrôle soit des slots non attribués
en latin1.



Ils ne se passent rien. Perl les accepte comme tous les autres (en
fait, il n'y a pas de valeur inacceptable en iso-8859-1). En UTF8,
Perl accepte encore tout. Il n'y a que lors d'une conversion qu'il
risque d'émettre un warning si le caractère n'existe pas ou s'il ne
peut pas le convertir vers l'encodage désiré.

--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>
Perl en français - <http://perl.enstimac.fr/>
Avatar
mpg
Le (on) dimanche 14 décembre 2008 10:12, Paul Gaborit a écrit (wrote) :

Pour l'instant, je tourne le problème en commençant par ouvrir le fichier
comme si c'était du latin1, jusqu'à tomber sur la déclaration d'encodage
: là je le ferme, puis le rouvre avec le bon encodage.



C'est une bonne solution. Tu peux même te passer de déclaration
d'encodage initialement puisque tu sais que c'est de l'ASCII.



En fait, j'utilise souvent

use open IO => ':utf8';

donc si je veux que ça soit lu autrement que de l'utf8, je suis obligé de
déclaré autre chose. Mais tu dis que je pourrais utiliser raw en fait ?

Ils ne se passent rien. Perl les accepte comme tous les autres (en
fait, il n'y a pas de valeur inacceptable en iso-8859-1).



Ok, c'est ce que je pensais mais je voulais être sûr.

En UTF8,
Perl accepte encore tout. Il n'y a que lors d'une conversion qu'il
risque d'émettre un warning si le caractère n'existe pas ou s'il ne
peut pas le convertir vers l'encodage désiré.



Euh, mais quand on rencontre une suite d'octets illégale en utf-8, il n'y a
pas un risque de dé-synchronisation puisqu'en fait on ne sait pas combien
d'octets correspondent au « caractère » inexistant ? Comme Perl tourne-t-il
le problème ?

Par ailleurs, ça veut dire que si j'ai de l'utf-8 illégal en entrée, selon
ce que j'en fais, Perl pourra ressortir de l'utf-8 illégal sans
avertissement. Ce n'est pas forcément choquant, mais c'est bon à savoir. Du
coup si je veux m'assurer que la chaîne est valide, il faut que je le fasse
à la main.

Manuel.
Avatar
Nicolas George
mpg wrote in message <gi5ikm$2shv$:
Euh, mais quand on rencontre une suite d'octets illégale en utf-8, il n'y a
pas un risque de dé-synchronisation puisqu'en fait on ne sait pas combien
d'octets correspondent au « caractère » inexistant ?



UTF-8 ne permet pas les désynchronisation, parce que ce ne sont pas les
mêmes valeurs qui servent comme premier octet d'un caractère ou comme ou
comme octets supplémentaires : un dommage est forcément récupéré dès le
début du caractère suivant.

Mais c'est néanmoins une mauvaise idée de lire comme de l'UTF-8 quelque
chose dont on ne sait pas que c'est censé en être.
Avatar
Paul Gaborit
À (at) Mon, 15 Dec 2008 13:30:13 +0100,
mpg écrivait (wrote):
Le (on) dimanche 14 décembre 2008 10:12, Paul Gaborit a écrit (wrote) :

Pour l'instant, je tourne le problème en commençant par ouvrir le fichier
comme si c'était du latin1, jusqu'à tomber sur la déclaration d'encodage
: là je le ferme, puis le rouvre avec le bon encodage.



C'est une bonne solution. Tu peux même te passer de déclaration
d'encodage initialement puisque tu sais que c'est de l'ASCII.



En fait, j'utilise souvent

use open IO => ':utf8';

donc si je veux que ça soit lu autrement que de l'utf8, je suis obligé de
déclaré autre chose. Mais tu dis que je pourrais utiliser raw en fait ?



Pour la lecture jusqu'à trouver l'information d'encodage, c'est
faisable. Après, il faudra bien sûr utiliser le bon
encodage. L'intérêt de raw sur UTF8, c'est que tu ne risques pas de
rencontrer, accidentellement, une séquence qui, interprétée en utf8,
te ferait rater ce que tu cherches...

Dans le cas précis de LaTeX, la déclaration doit être au plus tôt dans
le fichier et précédée uniquement de caractères en ASCII. Donc tu ne
risques pas de rencontrer le problème.

Euh, mais quand on rencontre une suite d'octets illégale en utf-8,
il n'y a pas un risque de dé-synchronisation puisqu'en fait on ne
sait pas combien d'octets correspondent au « caractère » inexistant
? Comme Perl tourne-t-il le problème ?



perl accepte tout. En utf8, les fins de caractères sont les seuls
octets de valeurs inférieurs à 128. Ça permet de se re-synchroniser à
tous les coups.

Par ailleurs, ça veut dire que si j'ai de l'utf-8 illégal en entrée,
selon ce que j'en fais, Perl pourra ressortir de l'utf-8 illégal
sans avertissement. Ce n'est pas forcément choquant, mais c'est bon
à savoir. Du coup si je veux m'assurer que la chaîne est valide, il
faut que je le fasse à la main.



Je n'ai jamais testé. Si j'ai le temps, j'essaye et je te dis ce qui
se passe.


--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>
Perl en français - <http://perl.enstimac.fr/>
Avatar
Nicolas George
Paul Gaborit wrote in message :
Dans le cas précis de LaTeX, la déclaration doit être au plus tôt dans
le fichier et précédée uniquement de caractères en ASCII.



Ce n'est pas vrai du tout. Il peut y avoir une foule de commentaires avec
plein d'accents avant le usepackage[xxx]{inputenc}. Il peut même y avoir
des déclarations de macros avant (même si en pratique, personne ne met
jamais rien avant les usepackage).
Avatar
mpg
Le (on) lundi 15 décembre 2008 21:14, Nicolas George a écrit (wrote) :

Paul Gaborit wrote in message :
Dans le cas précis de LaTeX, la déclaration doit être au plus tôt dans
le fichier et précédée uniquement de caractères en ASCII.



Ce n'est pas vrai du tout. Il peut y avoir une foule de commentaires avec
plein d'accents avant le usepackage[xxx]{inputenc}. Il peut même y avoir
des déclarations de macros avant (même si en pratique, personne ne met
jamais rien avant les usepackage).



J'ai tendance à croire que Paul sait ça très bien, et que dans sa
phrase « doit » a plutôt le sens « devrait, si on veut éviter les ennuis »
que celui d'une obligation technique.

Et pour l'anecdote, ça m'arrive de mettre des trucs avant le documentclass,
en général sur la ligne de commande et justement pour passer au document
des infos déterminées par Perl...

Manuel.
Avatar
mpg
Le (on) lundi 15 décembre 2008 18:12, Paul Gaborit a écrit (wrote) :

Pour la lecture jusqu'à trouver l'information d'encodage, c'est
faisable. Après, il faudra bien sûr utiliser le bon
encodage. L'intérêt de raw sur UTF8, c'est que tu ne risques pas de
rencontrer, accidentellement, une séquence qui, interprétée en utf8,
te ferait rater ce que tu cherches...



Ok.

Dans le cas précis de LaTeX, la déclaration doit être au plus tôt dans
le fichier et précédée uniquement de caractères en ASCII. Donc tu ne
risques pas de rencontrer le problème.



En fait, dans le contexte où j'utilise le script, il y a en principe le nom
de l'auteur (potentiellement non-ascii donc) en commentaire en haut de
chaque fichier (enfin, ça serait le cas si mes étudiants m'écoutaient).

perl accepte tout. En utf8, les fins de caractères sont les seuls
octets de valeurs inférieurs à 128. Ça permet de se re-synchroniser à
tous les coups.



Ah, magnifique, c'est bien pensé UTF-8 :-) Je ne sais pas pourquoi j'avais
cru entendre à un époque qu'il pouvait y avoir des soucis, c'est bon de
savoir qu'en fait non.

Je n'ai jamais testé. Si j'ai le temps, j'essaye et je te dis ce qui
se passe.



Pareil :-)

Manuel.