Corriger les erreurs de détection d'encodage cyrillique en C# avec Ude
La bibliothèque Ude sous C# peut parfois mal identifier l'encodage des fichiers texte contenant des caractères cyrilliques, en rapportant erronément 'Macintosh' au lieu de Windows-1251. Cela provoque un affichage illisible — du texte russe correctement écrit apparaît comme du « mojibake ». Ce problème se manifeste aussi bien dans Notepad++ qu’au sein du code utilisant CharsetDetector.
Dans la méthode GetFileEncoding, Ude retourne cdet.Charset comme étant 'Macintosh', ce qui entraîne des erreurs lors de la conversion ultérieure :
public static Encoding GetFileEncoding(string filename)
{
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
using (FileStream fs = File.OpenRead(filename))
{
Ude.CharsetDetector cdet = new Ude.CharsetDetector();
cdet.Feed(fs);
cdet.DataEnd();
if (cdet.Charset != null)
{
return Encoding.GetEncoding(cdet.Charset);
}
}
return Encoding.GetEncoding(CodePages.Windows1251);
}
Appliquer cet encodage incorrect dans ChangeEncodingForMidFile aggrave le problème : le texte est lu de manière incorrecte et écrit dans un nouveau fichier corrompu.
private static void ChangeEncodingForMidFile(string midFile,
Encoding midFileEncoding,
string newFullMidFileName)
{
using StreamReader reader = new StreamReader(midFile, midFileEncoding);
using StreamWriter writer = new StreamWriter(
newFullMidFileName,
false,
Encoding.GetEncoding(CodePages.Windows1251)
);
writer.Write(reader.ReadToEnd());
File.Delete(midFile);
File.Move(newFullMidFileName, midFile);
}
Analyser les différences entre MacCyrillic et Windows-1251
Les encodages MacCyrillic (CodePages.Macintosh) et Windows-1251 utilisent des plages d’octets différentes pour les caractères cyrilliques. Pour un texte russe typique sans symboles rares, on peut repérer des « octets suspects » qui sont inhabituels dans un encodage mais fréquents dans l’autre :
- Suspect pour Macintosh : octets typiques de Windows-1251 (0xAB, 0xB8–0xB9, 0xBB, 0xC0–0xC7, 0xC9, 0xCB–0xCF, 0xD2–0xDB, 0xFF).
- Suspect pour Windows-1251 : octets typiques de Macintosh (0x80–0x8F, 0x90–0x97, 0x99–0x9F).
Ces ensembles servent à une revalidation heuristique.
private static readonly ArrayList<byte> StrangeForMacintoshBytes = new ArrayList<byte>
{
0xAB,
0xB8, 0xB9, 0xBB,
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC9, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB,
0xFF
};
private static readonly ArrayList<byte> StrangeForWindows1251Bytes = new ArrayList<byte>
{
0x80, 0x81, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F
};
Mettre en œuvre CustomGetEncoding
La méthode CustomGetEncoding est déclenchée lorsque Macintosh ou MacCyrillic est détecté :
if (cdet.Charset != null)
{
var encoding = Encoding.GetEncoding(cdet.Charset);
if (encoding.CodePage == CodePages.Macintosh || encoding.CodePage == CodePages.MacCyrillic)
return CustomGetEncoding(encoding, filename);
}
Logique de CustomGetEncoding :
- Parcourir les octets du fichier.
- Si un octet provenant de
StrangeForMacintoshBytesest trouvé — retourner Windows-1251. - Sinon, si un octet provenant de
StrangeForWindows1251Bytesest trouvé — retourner Macintosh. - Si aucun octet suspect n’est trouvé — par défaut, retourner Windows-1251.
Cette solution corrige le cas des textes russes simples, mais ne s’applique pas universellement.
Limites et recommandations
Inconvénients de cette approche :
- Restreinte aux textes cyrilliques sans caractères rares.
- Ne gère pas UTF-8 ni d’autres encodages.
- Repose sur des heuristiques, pas sur un mécanisme fiable de détection.
Pour les utilisateurs :
- Ouvrir le fichier dans Notepad++.
- Essayer différents encodages (Windows-1251, UTF-8) jusqu’à ce qu’il n’y ait plus de corruption.
- Copier le texte.
- Créer un nouveau fichier avec l’encodage cible et coller le contenu.
- Enregistrer le fichier.
Même cette solution manuelle ne garantit pas 100 % de succès si Ude détecte mal l’encodage malgré une lecture visuellement correcte.
D'autres bibliothèques de détection d’encodage présentent des problèmes similaires. La détection automatique est intrinsèquement probabiliste et dépend des fréquences d’octets présents dans le texte.
Points clés
- Ude confond fréquemment MacCyrillic et Windows-1251 pour les fichiers cyrilliques.
- Utiliser des heuristiques basées sur les « octets suspects » corrige la détection sans modifier la bibliothèque.
- Cette correction fonctionne uniquement pour les textes russes basiques.
- Toujours vérifier manuellement l’encodage dans Notepad++ avant traitement.
- La détection d’encodage est probabiliste — les erreurs sont inévitables.
— Editorial Team
Aucun commentaire pour le moment.