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

Détecter UTF-8

17 réponses
Avatar
aski
Bonjour,

J'ai utilisé, pour détecter le codage UTF-8 dans un fichier (php, html ou
autre fichier texte), les fonctions API WideCharToMultiByte() et
MultiByteToWideChar() appelées successivement.
Cette méthode ne fonctionne évidemment que s'il existe des codes ASCII
supérieurs à 127.
Connaissez-vous d'autres axes de récherche en VB6 ?

Merci
--
Cordialement

Aski
MVP Windows Desktop Experience

10 réponses

1 2
Avatar
Fred
Dans : news:,
aski écrivait :
Bonjour,



Bonjour,

J'ai utilisé, pour détecter le codage UTF-8 dans un fichier (php,
html ou autre fichier texte), les fonctions API WideCharToMultiByte()
et MultiByteToWideChar() appelées successivement.
Cette méthode ne fonctionne évidemment que s'il existe des codes ASCII
supérieurs à 127.



S'il n'existe pas d'octets supérieurs à 127, le fichier peut-être
considéré comme encodé en UTF-8 car il y a compatibilité avec l'ASKI sur
cette plage.

Connaissez-vous d'autres axes de récherche en VB6 ?



- Regarder en début de fichier s'il y a un Byte Order Mark (BOM).
- Analyser le fichier sommairement pour voir si la séquence d'octets est
conforme avec de l'UTF-8

Peut-être d'autres méthodes que j'ignore.

Pour l'analyse, les points suivants peuvent t'aider :
si l'octet est supérieur à 127, alors le nombre N de bits de poids fort
à 1 (avant le premier à 0 donc), correspond à la longueur de la
séquence. (une séquence = un caractère)
Les N-1 octets qui suivents doivent tous avoir leurs deux bits de poids
fort respectivement à 1 et 0.

http://fr.wikipedia.org/wiki/UTF-8


--
Fred

Avatar
jean-marc
"Fred" wrote in message
news:%23%
Dans : news:,
aski écrivait :
Bonjour,



Bonjour,

J'ai utilisé, pour détecter le codage UTF-8 dans un fichier (php,
html ou autre fichier texte), les fonctions API WideCharToMultiByte()
et MultiByteToWideChar() appelées successivement.
Cette méthode ne fonctionne évidemment que s'il existe des codes ASCII
supérieurs à 127.



S'il n'existe pas d'octets supérieurs à 127, le fichier peut-être
considéré comme encodé en UTF-8 car il y a compatibilité avec l'ASKI sur
cette plage.

Connaissez-vous d'autres axes de récherche en VB6 ?





Salut Aski,

En complément de la réponse déjà très complète de Fred, tu peux
aussi chercher (dans le cas d'un document html) l'attribut "charset"
qui doit normalement spécifier l'encodage:

<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">

Cordialement,


--
Jean-marc Noury (jean_marc_n2)
Microsoft MVP - Visual Basic
FAQ VB: http://faq.vb.free.fr/
mailto: remove '_no_spam_' ;
Avatar
aski
Hello jean-marc,

"jean-marc" a écrit dans le message de
groupe de discussion : 48ad5ec6$0$2862$

En complément de la réponse déjà très complète de Fred, tu peux
aussi chercher (dans le cas d'un document html) l'attribut "charset"
qui doit normalement spécifier l'encodage:

<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">



Oui, bien sûr, mais dans le cas du PHP, on se peut se trouver en face de
variables dynamiques qui ne peuvent être déterminées lorsqu'on édite ou
analyse un fichier isolé.
--
Cordialement

Aski
MVP Windows Desktop Experience
Avatar
aski
Salut Fred,

"Fred" a écrit dans le message de groupe de
discussion : ##
Dans : news:,
aski écrivait :
Bonjour,



Bonjour,

J'ai utilisé, pour détecter le codage UTF-8 dans un fichier (php,
html ou autre fichier texte), les fonctions API WideCharToMultiByte()
et MultiByteToWideChar() appelées successivement.
Cette méthode ne fonctionne évidemment que s'il existe des codes ASCII
supérieurs à 127.



S'il n'existe pas d'octets supérieurs à 127, le fichier peut-être
considéré comme encodé en UTF-8 car il y a compatibilité avec l'ASKI sur
cette plage.



Pourquoi pas ANSI (voir comment NotePad ++ l'interprète) ?.

Connaissez-vous d'autres axes de récherche en VB6 ?



- Regarder en début de fichier s'il y a un Byte Order Mark (BOM).



Cela, c'est facile et déjà fait, mais on peut être avec ou sans BOM.

- Analyser le fichier sommairement pour voir si la séquence d'octets est
conforme avec de l'UTF-8



Les API citées sont les seules que j'ai trouvées pour le faire.
En convertissant la chaîne en ANSi puis le résultat en UTF-8, la chaîne
résultante doit être le même que la chaîne initiale.

Peut-être d'autres méthodes que j'ignore.

Pour l'analyse, les points suivants peuvent t'aider :
si l'octet est supérieur à 127, alors le nombre N de bits de poids fort à
1 (avant le premier à 0 donc), correspond à la longueur de la séquence.
(une séquence = un caractère)
Les N-1 octets qui suivents doivent tous avoir leurs deux bits de poids
fort respectivement à 1 et 0.

http://fr.wikipedia.org/wiki/UTF-8



Merci, j'avais lu mais cela n'a pu me dépanner pour une détection rapide. On
pourrait aussi se servir de la longueur du fichier pour déterminer qu'il y a
possibilité de codage. Malheureusement, il y a ambiguïté lorsque les codes
des caractères sont inférieurs à 128.
--
Cordialement

Aski
MVP Windows Desktop Experience
Avatar
Fred
Dans : news:,
aski écrivait :
Salut Fred,



S'il n'existe pas d'octets supérieurs à 127, le fichier peut-être
considéré comme encodé en UTF-8 car il y a compatibilité avec l'ASKI
sur cette plage.



Pourquoi pas ANSI (voir comment NotePad ++ l'interprète) ?.



Idem, sur la plage 0 - 127, ASCII = ANSI
Mais dès qu'on dépasse 127 (en UTF-8), on est en présence d'un caractère
codé sur plusieurs octets.
Donc pas du tout compatible, ni avec ASCII, ni ANSI, ni n'importe quel
codage mono-octet.
(voir les «hiéroglyphes» que l'on peut parfois observer sur les
newsgroups lorque l'on réponds à un message UTF-8 posté du site MS avec
un lecteur mal configuré).


Connaissez-vous d'autres axes de récherche en VB6 ?



- Regarder en début de fichier s'il y a un Byte Order Mark (BOM).



Cela, c'est facile et déjà fait, mais on peut être avec ou sans BOM.



oui, je ne sous-entendais pas qu'il y avait équivalence.
BOM (correct) => UTF-8
La réciproque n'est pas vraie.

- Analyser le fichier sommairement pour voir si la séquence d'octets
est conforme avec de l'UTF-8



Les API citées sont les seules que j'ai trouvées pour le faire.
En convertissant la chaîne en ANSi puis le résultat en UTF-8, la
chaîne résultante doit être le même que la chaîne initiale.



C'est ce que j'avais compris de ta technique.


http://fr.wikipedia.org/wiki/UTF-8



Merci, j'avais lu mais cela n'a pu me dépanner pour une détection
rapide.



Rapide en temps d'écriture du code ;-)
Mais analyser le fichier en le lisant avec, pourquoi pas, un petit
automate d'état fini dont Jean-Marc a le secret, devrait être
extrêmement rapide !
Sans compter que tu peux ne lire les octets que par blocs et ne pas
charger le fichier entièrement en mémoire.

Malheureusement, il y a
ambiguïté lorsque les codes des caractères sont inférieurs à 128.



Ben non, c'est justement le seul cas où il n'y a jamais ambiguïté,
puisque tous les encodages (je parle de ASCII, ANSI(s), ISO, UTF-8) sont
équivalents sur cette plage.


--
Fred

Avatar
aski
Re,

"Fred" a écrit dans le message de groupe de
discussion :

Pourquoi pas ANSI (voir comment NotePad ++ l'interprète) ?.



Idem, sur la plage 0 - 127, ASCII = ANSI
Mais dès qu'on dépasse 127 (en UTF-8), on est en présence d'un caractère
codé sur plusieurs octets.



Tu veux bien dire que c'est un cas très spécifique à l'UTF-8 et que l'on ne
retrouve pas sur sur les autres codes ?

Donc pas du tout compatible, ni avec ASCII, ni ANSI, ni n'importe quel
codage mono-octet.
(voir les «hiéroglyphes» que l'on peut parfois observer sur les newsgroups
lorque l'on réponds à un message UTF-8 posté du site MS avec un lecteur
mal configuré).



Merci, j'avais lu mais cela n'a pu me dépanner pour une détection
rapide.



Rapide en temps d'écriture du code ;-)



Mais alors, pourquoi API il se décarcasse ? :o)

Mais analyser le fichier en le lisant avec, pourquoi pas, un petit
automate d'état fini dont Jean-Marc a le secret, devrait être extrêmement
rapide !



Je ne joue pas dans la même catégorie de Jean-Marc et je le regrette. :-(

Sans compter que tu peux ne lire les octets que par blocs et ne pas
charger le fichier entièrement en mémoire.



D'accord pour la méthode mais il faut se farcir la comparaison à tous les
couples d'octets après avoir déterminé qu'un octet au moins est dans la
plage > 127.

Malheureusement, il y a
ambiguïté lorsque les codes des caractères sont inférieurs à 128.



Ben non, c'est justement le seul cas où il n'y a jamais ambiguïté, puisque
tous les encodages (je parle de ASCII, ANSI(s), ISO, UTF-8) sont
équivalents sur cette plage.



C'est ce que je veux dire dans mon jargon trop simpliste .... Notepad
indique un format ANSI dans ce cas alors qu'il devrait indiquer par exemple
"neutre" ou "non détectable"
--
Cordialement

Aski
MVP Windows Desktop Experience
Avatar
Jean-marc
aski wrote:
Re,
Mais analyser le fichier en le lisant avec, pourquoi pas, un petit
automate d'état fini dont Jean-Marc a le secret, devrait être
extrêmement rapide !





Je confirme :o) Couplé avec une lecture binaire rapide si le fichier
n'est pas trop volumineux (http://faq.vb.free.fr/index.php?question5),
ce devrait être extrèmement efficace !

Je ne joue pas dans la même catégorie de Jean-Marc et je le regrette.
:-(



C'est trop d'honneur :-)

Rien de bien compliqué en soi dans les automates. Je pense que l'exemple
que j'ai indiqué dans la FAQ doit permettre de comprendre le principe:
http://faq.vb.free.fr/index.php?question3

Ceci dit, je suis sur que François (actuellement en vacances) aurait des
idées brillantes sur le sujet. C'est lui le super expert des encodages
et autres joyeusetés du même accabit... Peut être reposter pour mémoire lors
de
son retour ?

Bonne soirée !

--
Jean-marc Noury (jean_marc_n2)
Microsoft MVP - Visual Basic
FAQ VB: http://faq.vb.free.fr/
mailto: remove '_no_spam_' ;
Avatar
Fred
Dans : news:,
aski écrivait :
Re,

"Fred" a écrit dans le message de groupe de
discussion :

Pourquoi pas ANSI (voir comment NotePad ++ l'interprète) ?.



Idem, sur la plage 0 - 127, ASCII = ANSI
Mais dès qu'on dépasse 127 (en UTF-8), on est en présence d'un
caractère codé sur plusieurs octets.



Tu veux bien dire que c'est un cas très spécifique à l'UTF-8 et que
l'on ne retrouve pas sur sur les autres codes ?



Non, pas exactement.
(UTF-8) => (critères vérifiés)
(critères non vérifiés) => (non UTF-8)
mais (critères vérifiés) n'implique pas UTF-8

ex : Dans un fichier ANSI je place, avec Notepad, les deux caractères
suivants :
é
J'obtiens, si on ne considère pas le BOM qui sera absent, un fichier qui
satisfait les critères UTF-8.
Interprété comme de l'UTF-8, les deux octets du fichier représentent le
caractère é.

Bien sûr la probabilité que les critères soient vérifiés et que le
fichier ne soit pas de l'UTF-8 est faible.
Mais je pense que dans ce cas, même les APIs se «plantent».

C'est ce que je veux dire dans mon jargon trop simpliste .... Notepad
indique un format ANSI dans ce cas alors qu'il devrait indiquer par
exemple "neutre" ou "non détectable"



Oui, c'est moi qui ai mal compris ce que tu voulais dire.
Pourquoi ANSI ? Peut-être parce que c'est l'encodage par défaut du
système ?


--
Fred

Avatar
Fred
Dans : news:48adcf7f$0$2856$,
Jean-marc écrivait :
aski wrote:
Re,





Hello Jean-Marc

Mais analyser le fichier en le lisant avec, pourquoi pas, un petit
automate d'état fini dont Jean-Marc a le secret, devrait être
extrêmement rapide !





Je confirme :o) Couplé avec une lecture binaire rapide si le fichier
n'est pas trop volumineux
(http://faq.vb.free.fr/index.php?question5), ce devrait être
extrèmement efficace !



Oui, mais contrairement à ce qui est proposé dans ton article (et pour
ce cas j'entends), je resterais en interprétation binaire. Soit à
déclarer le buffer en tableau d'octets et non en chaîne. Ce qui devrait
d'ailleurs diviser par deux l'espace mémoire utilisé. Et ensuite
faciliter le traitement des octets en effectuant des masquages binaires.
octet And 10000000 = 00000000 => caractère mono-octet
octet And 11100000 = 11000000 => premier octet d'un caractère sur deux
octets
octet And 11110000 = 11100000 => premier octet d'un caractère sur trois
octets
octet And 11111000 = 11110000 => premier octet d'un caractère sur quatre
octets
octet And 11000000 = 10000000 => octet de suite d'un caractère
multi-octets

Pour être complet, il y a des séquences non valides en UTF-8 qu'il
faudrait traiter mais je crois que l'article sur wikipedia y fait
référence. Sinon, voir par exemple ici :
http://www.ietf.org/rfc/rfc3629.txt

--
Fred

Avatar
aski
"Fred" a écrit dans le message de groupe de
discussion :

Non, pas exactement.
(UTF-8) => (critères vérifiés)
(critères non vérifiés) => (non UTF-8)
mais (critères vérifiés) n'implique pas UTF-8

ex : Dans un fichier ANSI je place, avec Notepad, les deux caractères
suivants :
é
J'obtiens, si on ne considère pas le BOM qui sera absent, un fichier qui
satisfait les critères UTF-8.
Interprété comme de l'UTF-8, les deux octets du fichier représentent le
caractère é.



Encore plus flagrant d'ailleurs si on place éé.
Ceci prouve donc que c'est bien la détection de é qui est prise en
priorité.

Bien sûr la probabilité que les critères soient vérifiés et que le fichier
ne soit pas de l'UTF-8 est faible.
Mais je pense que dans ce cas, même les APIs se «plantent».



J'essaierai.

Oui, c'est moi qui ai mal compris ce que tu voulais dire.
Pourquoi ANSI ? Peut-être parce que c'est l'encodage par défaut du système
?



Ce n'est quand-même pas très sérieux pour un utilitaire de cette qualité.
--
Cordialement

Aski
MVP Windows Desktop Experience
1 2