Rumah >pembangunan bahagian belakang >C++ >Bagaimanakah Saya Boleh Menentukan Pengekodan Rentetan dalam C#?

Bagaimanakah Saya Boleh Menentukan Pengekodan Rentetan dalam C#?

Barbara Streisand
Barbara Streisandasal
2025-01-20 19:14:241026semak imbas

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

Menentukan Pengekodan Rentetan dalam C#

Adakah terdapat cara untuk menentukan pengekodan rentetan dalam C#? Sebagai contoh, jika anda mempunyai rentetan nama fail tetapi tidak pasti sama ada ia dikodkan dalam UTF-16 atau pengekodan lalai sistem, panduan ini menunjukkan cara untuk menentukan pengekodannya.

Penyelesaian:

Kod di bawah mempunyai keupayaan berikut:

  • Mengesan UTF-7, UTF-8/16/32 (bom, no bom, little & big endian)
  • Berbalik kepada halaman kod lalai setempat jika tiada pengekodan Unikod ditemui
  • Mengesan (dengan kebarangkalian tinggi) fail unicode dengan BOM/tandatangan tiada
  • Mencari charset=xyz dan encoding=xyz dalam fail untuk membantu menentukan pengekodan
  • Parameter 'taster' yang boleh disesuaikan untuk mengawal bilangan bait untuk diperiksa
  • Mengembalikan pengekodan dan fail teks yang dinyahkod
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;
}

Atas ialah kandungan terperinci Bagaimanakah Saya Boleh Menentukan Pengekodan Rentetan dalam C#?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn