Zurück zur Startseite

Ude Kyrillisch-Fehler C# Codierungs-Erkennung

Der Artikel analysiert das Problem der falschen Kyrillisch-Codierungs-Erkennung durch Ude-Bibliothek in C#. Eine heuristische Methode basierend auf 'seltsamen' Bytes wird vorgeschlagen, um Macintosh/Windows-1251 zu korrigieren. Code, Einschränkungen und Empfehlungen zur manuellen Verifizierung werden beschrieben.

Ude-Fehlerbehebung: Kyrillisch in C# ohne mojibake
Advertisement 728x90

Cyrillische Zeichencodierung in C# korrigieren: Ude-Fehler beheben

Die Bibliothek Ude erkennt in C# gelegentlich die Codierung von Textdateien mit kyrillischen Zeichen falsch und meldet stattdessen 'Macintosh' anstelle von Windows-1251. Dies führt zu verschobenem Text beim Lesen – russische Texte, die eigentlich lesbar sein sollten, erscheinen als unleserliches 'Mojibake'. Das Problem tritt sowohl in Notepad++ als auch in Code auf, der CharsetDetector nutzt.

In der Methode GetFileEncoding gibt Ude cdet.Charset als 'Macintosh' zurück, was bei nachfolgenden Umwandlungen zu Fehlern führt:

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);
}

Die Anwendung dieser falschen Codierung in ChangeEncodingForMidFile verschärft das Problem: Der Text wird falsch gelesen und in einer neuen Datei mit Beschädigung gespeichert.

Google AdInline article slot
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);
}

Unterschiede zwischen MacCyrillic und Windows-1251 analysieren

Die Codierungen MacCyrillic (CodePages.Macintosh) und Windows-1251 verwenden unterschiedliche Byte-Bereiche für kyrillische Zeichen. Für typische russische Texte ohne seltene Symbole können wir "verdächtige" Bytes identifizieren, die für eine Codierung untypisch sind, aber für die andere charakteristisch sind:

  • Verdächtig für Macintosh: Bytes, die typisch für Windows-1251 sind (0xAB, 0xB8–0xB9, 0xBB, 0xC0–0xC7, 0xC9, 0xCB–0xCF, 0xD2–0xDB, 0xFF).
  • Verdächtig für Windows-1251: Bytes, die typisch für Macintosh sind (0x80–0x8F, 0x90–0x97, 0x99–0x9F).

Diese Mengen dienen zur heuristischen Überprüfung.

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
};

Benutzerdefinierte Codierungserkennung implementieren

Die Methode CustomGetEncoding wird ausgelöst, wenn Macintosh oder MacCyrillic erkannt wird:

Google AdInline article slot
if (cdet.Charset != null)
{
    var encoding = Encoding.GetEncoding(cdet.Charset);
    if (encoding.CodePage == CodePages.Macintosh || encoding.CodePage == CodePages.MacCyrillic)
        return CustomGetEncoding(encoding, filename);
}

Logik von CustomGetEncoding:

  • Durchsuche die Bytes der Datei.
  • Wenn ein Byte aus StrangeForMacintoshBytes gefunden wird – gib Windows-1251 zurück.
  • Andernfalls, wenn ein Byte aus StrangeForWindows1251Bytes gefunden wird – gib Macintosh zurück.
  • Falls keine verdächtigen Bytes gefunden werden – standardmäßig Windows-1251.

Dies löst den Fall für einfache russische Texte, ist aber nicht universell anwendbar.

Grenzen und Empfehlungen

Nachteile dieses Ansatzes:

Google AdInline article slot
  • Beschränkt auf kyrillische Texte ohne seltene Zeichen.
  • Behandelt UTF-8 oder andere Codierungen nicht.
  • Beruht auf Heuristiken, kein zuverlässiger Erkennungsmechanismus.

Für Nutzer:

  • Öffne die Datei in Notepad++.
  • Probiere verschiedene Codierungen (Windows-1251, UTF-8), bis keine Verzerrung mehr auftritt.
  • Kopiere den Text.
  • Erstelle eine neue Datei mit der Ziel-Codierung und füge den Inhalt ein.
  • Speichere sie ab.

Auch diese manuelle Lösung garantiert nicht zu 100 % Erfolg, falls Ude die Codierung dennoch falsch erkennt, obwohl der Text visuell korrekt erscheint.

Andere Bibliotheken zur Zeichencodierungserkennung zeigen ähnliche Probleme. Die automatische Erkennung ist grundsätzlich probabilistisch und hängt von Byte-Häufigkeitsmustern im Text ab.

Wichtige Erkenntnisse

  • Ude verwechselt häufig MacCyrillic und Windows-1251 bei kyrillischen Dateien.
  • Die Nutzung von "verdächtigen Bytes" als Heuristik behebt die Erkennung, ohne die Bibliothek zu ändern.
  • Die Lösung funktioniert nur für grundlegende russische Texte.
  • Überprüfe immer die Codierung manuell in Notepad++ vor der Verarbeitung.
  • Zeichencodierungserkennung ist probabilistisch – Fehler sind unvermeidlich.

— Editorial Team

Advertisement 728x90

Weiterlesen