J'ai besoin de traiter une grande liste de cordes courtes (principalement en russe, mais toute autre langue est possible, y compris des ordures aléatoires d'un chat marchant sur le clavier).
Certaines de ces chaînes seront codées dans UTF-8 deux fois. p>
J'ai besoin de détecter de manière fiable si une chaîne donnée est à double codée et le réparer. Je devrais le faire sans utiliser de bibliothèques externes, simplement en inspectant les octets. La détection doit être aussi rapide que possible. P>
La question est la suivante: Comment détecter qu'une chaîne donnée a été codée dans UTF-8 deux fois? P>
mise à jour: EM> > p> Les chaînes originales sont dans UTF-8. Voici le code AS3 qui fait le second encodage (malheureusement, je n'ai pas de contrôle sur le code client, donc je ne peux donc pas résoudre ce problème): p> note tolowercase () code> appel. Peut-être que cela peut aider? P> p>
3 Réponses :
En principe, vous ne pouvez pas, surtout pour permettre aux ordures cates. p>
Vous ne dites pas ce que le codage de caractères d'origine des données était avant qu'il a été codé UTF-8 une ou deux fois. Je suppose que cp1251 (ou du moins que CP1251 est l'une des possibilités) car c'est un cas assez délicat. P>
Prendre un caractère non ASCII. UTF-8 encoder. Vous obtenez des octets et tous ces octets sont des caractères valides dans CP1251, à moins que l'un d'entre eux ne soit 0x98, le seul trou de CP1251. P>
Donc, si vous convertissez ces octets de CP1251 en UTF-8, le résultat est exactement le même que si vous avez correctement codé UTF-8 codé une chaîne CP1251 composée de ces caractères russes. Il n'ya aucun moyen de dire si le résultat provient de manière incorrecte à double codage d'un caractère, ou correctement codant sur 2 caractères. P>
Si vous avez un certain contrôle sur les données d'origine, vous pouvez mettre un nom à l'heure du début. Ensuite, quand il vous revient, inspectez les octets initiaux pour voir si vous avez une naissance UTF-8, ou le résultat d'un codage incorrect à double codage. Mais je suppose que vous n'avez probablement pas ce genre de contrôle sur le texte original. P>
En pratique, vous pouvez deviner - UTF-8 décode et ensuite: p>
(a) Regardez les fréquences de caractères, les fréquences de paires de caractères, les nombres de caractères non imprimables. Cela pourrait vous permettre de déclarer provisoirement une non-sens, et donc éventuellement à double codation. Avec suffisamment de caractères non imprimables, il peut être si absurde que vous ne pouviez pas le taper de manière réaliste même en écrasant au clavier, à moins que votre clé alt était bloquée. P>
(b) tente la deuxième décode. C'est-à-dire à partir des points de code Unicode que vous avez obtenu en décodage de vos données UTF-8, d'abord le coder à CP1251 (ou autre), puis décodez le résultat de l'UTF-8. Si l'une ou l'autre étape échoue (en raison de séquences non valides d'octets), elle n'était certainement pas à double codée, du moins de ne pas utiliser CP1251 comme interprétation défectueuse. P>
C'est plus ou moins ce que vous faites si vous avez des octets qui pourraient être UTF-8 ou pourraient être CP1251, et vous ne savez pas lequel. P>
Vous obtiendrez des faux positifs pour les ordures cates codées à une seule-codée indiscernables des données à double codée, et peut-être un très peu de faux négatifs pour les données à double codation, mais qu'après le premier encodé par Fluke ressemblait à la russe. . p>
Si votre codage d'origine a plus de trous de la CP1251, vous aurez moins de faux négatifs. P>
Les codages de caractères sont durs. P>
Vous avez raison, je n'ai pas de contrôle sur les chaînes d'origine. Mais j'ai mis à jour la question avec plus d'informations, peut-être que cela aidera.
Il n'y a rien de spécial sur la nomenclature codée à UTF-8 le marquant comme UTF-8 au lieu de déchets dans tout autre codage.
Voici un algorithme PHP qui a fonctionné pour moi.
Il est préférable de réparer vos données, mais si vous ne pouvez pas voici une astuce: p> La bibliothèque que j'utilise est la suivante:
https://github.com/neitanod/foreutf8/ p> p>
Quels sont les taux d'erreur pour l'entrée attendue?
if (mb_detect_encoding(mb_convert_encoding($string,'Windows-1251','UTF-8'),'Windows-1251,UTF-8',true) === 'UTF-8' ){ $string=mb_convert_encoding($string,'Windows-1251','UTF-8'); };
Quels sont les taux d'erreur pour l'entrée attendue?
Qu'entendez-vous par double codé dans utf8 ??
@Martin: FWIW, ma réponse suppose que cela signifie prendre du texte dans le codage X, le transformer en octets UTF-8, puis prendre ces octets, les réinterpréter comme codant x et transformer cela en octets UTF-8. En d'autres termes, que se passe-t-il lorsque vous interprétez de manière incorrecte un fichier de fichiers UTF-8 comme ISO-8859-1 (ou autre), puis "le convertir en UTF-8".
Eh bien, le texte original était dans UTF-8 et il est à nouveau codé dans UTF-8 par la bibliothèque client de Buggy. (Je vais essayer d'obtenir plus de détails sur ce qui codant de cette bibliothèque supposé le texte.)