Volver al inicio

Errores Ude cirílico C# detección de codificación

El artículo analiza el problema de detección incorrecta de codificación cirílica por la biblioteca Ude en C#. Se propone un método heurístico basado en bytes 'extraños' para corregir Macintosh/Windows-1251. Se describen código, limitaciones y recomendaciones de verificación manual.

Corrección de errores de Ude: cirílico en C# sin mojibake
Advertisement 728x90

Corrigiendo errores de detección de codificación cirílica en C# con Ude

La biblioteca Ude en C# a veces identifica incorrectamente la codificación de archivos de texto que contienen caracteres cirílicos, reportando erróneamente 'Macintosh' en lugar de Windows-1251. Esto provoca texto corrupto al leerlo—lo que debería ser ruso legible aparece como 'mojibake' ilegible. El problema se manifiesta tanto en Notepad++ como en código que utiliza CharsetDetector.

En el método GetFileEncoding, Ude devuelve cdet.Charset como 'Macintosh', lo que causa errores durante la conversión posterior:

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

Aplicar esta codificación incorrecta en ChangeEncodingForMidFile agrava el problema: el texto se lee de forma inadecuada y se escribe en un nuevo archivo con corrupción.

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

Analizando las diferencias entre MacCirílico y Windows-1251

Las codificaciones MacCirílico (CodePages.Macintosh) y Windows-1251 utilizan rangos de bytes diferentes para los caracteres cirílicos. Para textos rusos típicos sin símbolos raros, podemos identificar "bytes sospechosos" que son poco característicos de una codificación pero comunes en la otra:

  • Sospechosos para Macintosh: Bytes típicos de Windows-1251 (0xAB, 0xB8–0xB9, 0xBB, 0xC0–0xC7, 0xC9, 0xCB–0xCF, 0xD2–0xDB, 0xFF).
  • Sospechosos para Windows-1251: Bytes típicos de Macintosh (0x80–0x8F, 0x90–0x97, 0x99–0x9F).

Estos conjuntos se usan para una revalidación heurística.

private static readonly ArrayList<byte> StrangeForMacintochBytes = 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
};

Implementando CustomGetEncoding

El método CustomGetEncoding se activa cuando se detecta Macintosh o MacCirílico:

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

Lógica de CustomGetEncoding:

  • Escanea los bytes del archivo.
  • Si se encuentra un byte de StrangeForMacintochBytes — devuelve Windows-1251.
  • Si no, pero hay un byte de StrangeForWindows1251Bytes — devuelve Macintosh.
  • Si no hay bytes sospechosos — por defecto devuelve Windows-1251.

Esto resuelve el caso para textos rusos básicos, pero no es aplicable universalmente.

Limitaciones y recomendaciones

Desventajas de este enfoque:

Google AdInline article slot
  • Solo funciona con textos cirílicos sin caracteres raros.
  • No maneja UTF-8 ni otras codificaciones.
  • Depende de heurísticas, no de un mecanismo confiable de detección.

Para usuarios:

  • Abre el archivo en Notepad++.
  • Prueba diferentes codificaciones (Windows-1251, UTF-8) hasta que no haya corrupción.
  • Copia el texto.
  • Crea un nuevo archivo con la codificación objetivo y pégalo.
  • Guárdalo.

Incluso este trabajo manual no garantiza un 100% de éxito si Ude identifica mal la codificación, a pesar de que el texto se ve correcto visualmente.

Otras bibliotecas de detección de codificación presentan problemas similares. La detección automática es inherentemente probabilística y depende de patrones de frecuencia de bytes en el texto.

Conclusiones clave

  • Ude suele confundir MacCirílico y Windows-1251 en archivos cirílicos.
  • Usar heurísticas basadas en "bytes sospechosos" corrige la detección sin modificar la biblioteca.
  • La solución solo funciona para textos rusos básicos.
  • Siempre verifica manualmente la codificación en Notepad++ antes de procesar.
  • La detección de codificación es probabilística: los errores son inevitables.

— Editorial Team

Advertisement 728x90

Leer después