Maison >développement back-end >C++ >Comment puis-je déterminer l'encodage d'une chaîne en C# ?

Comment puis-je déterminer l'encodage d'une chaîne en C# ?

Barbara Streisand
Barbara Streisandoriginal
2025-01-20 19:14:241026parcourir

How Can I Determine a String's Encoding in C#?

Détermination de l'encodage d'une chaîne en C#

Existe-t-il un moyen de déterminer l'encodage d'une chaîne en C# ? Par exemple, si vous avez une chaîne de nom de fichier mais que vous ne savez pas si elle est codée en UTF-16 ou dans le codage par défaut du système, ce guide montre comment déterminer son codage.

Solution :

Le code ci-dessous a les capacités suivantes :

  • Détecte UTF-7, UTF-8/16/32 (bom, no bom, little & big endian)
  • Revient à la page de codes locale par défaut si aucun encodage Unicode n'est trouvé
  • Détecte (avec une forte probabilité) l'Unicode fichiers avec la nomenclature/signature manquante
  • Recherche charset=xyz et encoding=xyz dans le fichier pour aider à déterminer encoding
  • Paramètre 'taster' personnalisable pour contrôler le nombre d'octets à vérifier
  • Renvoie l'encodage et le fichier texte décodé
public Encoding detectTextEncoding(string filename, out String text, int taster = 1000)
{
    byte[] b = File.ReadAllBytes(filename);

    // Check for BOM/signature
    if (b.Length >= 4 && b[0] == 0x00 && b[1] == 0x00 && b[2] == 0xFE && b[3] == 0xFF)
    {
        text = Encoding.GetEncoding("utf-32BE").GetString(b, 4, b.Length - 4);
        return Encoding.GetEncoding("utf-32BE");
    }
    else if (b.Length >= 4 && b[0] == 0xFF && b[1] == 0xFE && b[2] == 0x00 && b[3] == 0x00)
    {
        text = Encoding.UTF32.GetString(b, 4, b.Length - 4); 
        return Encoding.UTF32;
    }
    else if (b.Length >= 2 && b[0] == 0xFE && b[1] == 0xFF)
    {
        text = Encoding.BigEndianUnicode.GetString(b, 2, b.Length - 2);
        return Encoding.BigEndianUnicode;
    }
    else if (b.Length >= 2 && b[0] == 0xFF && b[1] == 0xFE)
    {
        text = Encoding.Unicode.GetString(b, 2, b.Length - 2); 
        return Encoding.Unicode;
    }
    else if (b.Length >= 3 && b[0] == 0xEF && b[1] == 0xBB && b[2] == 0xBF)
    {
        text = Encoding.UTF8.GetString(b, 3, b.Length - 3); 
        return Encoding.UTF8;
    }
    else if (b.Length >= 3 && b[0] == 0x2b && b[1] == 0x2f && b[2] == 0x76)
    {
        text = Encoding.UTF7.GetString(b, 3, b.Length - 3); 
        return Encoding.UTF7;
    }

    // Check for UTF8 without a BOM/signature
    bool utf8 = false;
    int i = 0;
    while (i < taster - 4)
    {
        if (b[i] <= 0x7F) { i += 1; continue; }
        if (b[i] >= 0xC2 && b[i] < 0xE0 && b[i + 1] >= 0x80 && b[i + 1] < 0xC0) { i += 2; utf8 = true; continue; }
        if (b[i] >= 0xE0 && b[i] < 0xF0 && b[i + 1] >= 0x80 && b[i + 1] < 0xC0 && b[i + 2] >= 0x80 && b[i + 2] < 0xC0) { i += 3; utf8 = true; continue; }
        if (b[i] >= 0xF0 && b[i] < 0xF5 && b[i + 1] >= 0x80 && b[i + 1] < 0xC0 && b[i + 2] >= 0x80 && b[i + 2] < 0xC0 && b[i + 3] >= 0x80 && b[i + 3] < 0xC0) { i += 4; utf8 = true; continue; }
        utf8 = false; break;
    }
    if (utf8 == true)
    {
        text = Encoding.UTF8.GetString(b);
        return Encoding.UTF8;
    }

    // Check for UTF-16 without BOM/signature
    double threshold = 0.1;
    int count = 0;
    for (int n = 0; n < taster; n += 2) if (b[n] == 0) count++;
    if (((double)count) / taster > threshold)
    {
        text = Encoding.BigEndianUnicode.GetString(b);
        return Encoding.BigEndianUnicode; 
    }
    count = 0;
    for (int n = 1; n < taster; n += 2) if (b[n] == 0) count++;
    if (((double)count) / taster > threshold)
    {
        text = Encoding.Unicode.GetString(b);
        return Encoding.Unicode; 
    }

    // Check for "charset=xyz" or "encoding=xyz"
    for (int n = 0; n < taster - 9; n++)
    {
        if ((b[n + 0] == 'c' || b[n + 0] == 'C') && (b[n + 1] == 'h' || b[n + 1] == 'H') && (b[n + 2] == 'a' || b[n + 2] == 'A') && (b[n + 3] == 'r' || b[n + 3] == 'R') && (b[n + 4] == 's' || b[n + 4] == 'S') && (b[n + 5] == 'e' || b[n + 5] == 'E') && (b[n + 6] == 't' || b[n + 6] == 'T') && (b[n + 7] == '='))
        {
            n += 8;
            if (b[n] == '&quot;' || b[n] == '\'') n++;
            int oldn = n;
            while (n < taster &amp;&amp; (b[n] == '_' || b[n] == '-' || (b[n] >= '0' && b[n] <= '9') || (b[n] >= 'a' && b[n] <= 'z') || (b[n] >= 'A' && b[n] <= 'Z'))) n++;
            byte[] nb = new byte[n - oldn];
            Array.Copy(b, oldn, nb, 0, n - oldn);
            try
            {
                string internalEnc = Encoding.ASCII.GetString(nb);
                text = Encoding.GetEncoding(internalEnc).GetString(b);
                return Encoding.GetEncoding(internalEnc);
            }
            catch { break; }
        }
    }

    // Fallback to local default codepage
    text = Encoding.Default.GetString(b);
    return Encoding.Default;
}

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn