it-swarm.asia

كيف يتم تحويل UTF-8 byte [] إلى سلسلة؟

لدي صفيف byte[] الذي تم تحميله من ملف أجده معروفًا يحتوي على UTF-8 . في بعض تعليمات تصحيح الأخطاء ، أحتاج إلى تحويلها إلى سلسلة. هل هناك بطانة واحدة ستقوم بذلك؟

تحت الأغطية ، يجب أن يكون مجرد تخصيص و memcopy ، لذلك حتى إذا لم يتم تنفيذه ، فيجب أن يكون ذلك ممكنًا.

833
BCS
string result = System.Text.Encoding.UTF8.GetString(byteArray);
1327
Zanoni

هناك أربع طرق مختلفة على الأقل للقيام بهذا التحويل.

  1. ترميز GetString
    ، لكن لن تتمكن من استعادة وحدات البايت الأصلية إذا كانت هذه البايتات تحتوي على أحرف غير ASCII.

  2. BitConverter.ToString
    الإخراج عبارة عن سلسلة محددة بـ "-" ، ولكن لا توجد طريقة .NET مدمجة لتحويل السلسلة إلى صفيف البايت.

  3. Convert.ToBase64String
    يمكنك بسهولة تحويل سلسلة الإخراج إلى صفيف البايت باستخدام Convert.FromBase64String.
    ملاحظة: يمكن أن تحتوي سلسلة الإخراج على '+' ، '/' و '='. إذا كنت تريد استخدام السلسلة في عنوان URL ، فأنت بحاجة إلى ترميزها بشكل صريح.

  4. HttpServerUtility.UrlTokenEncode
    يمكنك بسهولة تحويل سلسلة الإخراج إلى صفيف البايت باستخدام HttpServerUtility.UrlTokenDecode. سلسلة الإخراج هو بالفعل URL ودية! الجانب السلبي هو أنه يحتاج إلى System.Web التجميع إذا كان مشروعك ليس مشروع ويب.

مثال كامل:

byte[] bytes = { 130, 200, 234, 23 }; // A byte array contains non-ASCII (or non-readable) characters

string s1 = Encoding.UTF8.GetString(bytes); // ���
byte[] decBytes1 = Encoding.UTF8.GetBytes(s1);  // decBytes1.Length == 10 !!
// decBytes1 not same as bytes
// Using UTF-8 or other Encoding object will get similar results

string s2 = BitConverter.ToString(bytes);   // 82-C8-EA-17
String[] tempAry = s2.Split('-');
byte[] decBytes2 = new byte[tempAry.Length];
for (int i = 0; i < tempAry.Length; i++)
    decBytes2[i] = Convert.ToByte(tempAry[i], 16);
// decBytes2 same as bytes

string s3 = Convert.ToBase64String(bytes);  // gsjqFw==
byte[] decByte3 = Convert.FromBase64String(s3);
// decByte3 same as bytes

string s4 = HttpServerUtility.UrlTokenEncode(bytes);    // gsjqFw2
byte[] decBytes4 = HttpServerUtility.UrlTokenDecode(s4);
// decBytes4 same as bytes
298
detale

حل عام للتحويل من صفيف البايت إلى السلسلة عندما لا تعرف التشفير:

static string BytesToStringConverted(byte[] bytes)
{
    using (var stream = new MemoryStream(bytes))
    {
        using (var streamReader = new StreamReader(stream))
        {
            return streamReader.ReadToEnd();
        }
    }
}
21
Nir

فريف:

public static string ConvertByteToString(this byte[] source)
{
    return source != null ? System.Text.Encoding.UTF8.GetString(source) : null;
}

عن طريق:

string result = input.ConvertByteToString();
12
Erçin Dedeoğlu

يبدو تحويل byte[] إلى string بسيطًا ، ولكن من المحتمل أن يؤدي أي نوع من الترميز إلى تعطل سلسلة الإخراج. هذه الوظيفة الصغيرة تعمل فقط دون أي نتائج غير متوقعة:

private string ToString(byte[] bytes)
{
    string response = string.Empty;

    foreach (byte b in bytes)
        response += (Char)b;

    return response;
}
9
AndrewJE

باستخدام (byte)b.ToString("x2") ، المخرجات b4b5dfe475e58b67

public static class Ext {

    public static string ToHexString(this byte[] hex)
    {
        if (hex == null) return null;
        if (hex.Length == 0) return string.Empty;

        var s = new StringBuilder();
        foreach (byte b in hex) {
            s.Append(b.ToString("x2"));
        }
        return s.ToString();
    }

    public static byte[] ToHexBytes(this string hex)
    {
        if (hex == null) return null;
        if (hex.Length == 0) return new byte[0];

        int l = hex.Length / 2;
        var b = new byte[l];
        for (int i = 0; i < l; ++i) {
            b[i] = Convert.ToByte(hex.Substring(i * 2, 2), 16);
        }
        return b;
    }

    public static bool EqualsTo(this byte[] bytes, byte[] bytesToCompare)
    {
        if (bytes == null && bytesToCompare == null) return true; // ?
        if (bytes == null || bytesToCompare == null) return false;
        if (object.ReferenceEquals(bytes, bytesToCompare)) return true;

        if (bytes.Length != bytesToCompare.Length) return false;

        for (int i = 0; i < bytes.Length; ++i) {
            if (bytes[i] != bytesToCompare[i]) return false;
        }
        return true;
    }

}
8
metadings

هناك أيضا فئة UnicodeEncoding ، بسيطة جدا في الاستخدام:

ByteConverter = new UnicodeEncoding();
string stringDataForEncoding = "My Secret Data!";
byte[] dataEncoded = ByteConverter.GetBytes(stringDataForEncoding);

Console.WriteLine("Data after decoding: {0}", ByteConverter.GetString(dataEncoded));
5
P.K.

بدلا من ذلك:

 var byteStr = Convert.ToBase64String(bytes);
2
Fehr

على حد علمي ، فإن أياً من الإجابات المقدمة لا تضمن السلوك الصحيح بإنهاء لاغٍ. حتى يظهر لي شخص ما بشكل مختلف ، كتبت صفي الثابت الخاص للتعامل مع هذا بالطرق التالية:

// Mimics the functionality of strlen() in c/c++
// Needed because niether StringBuilder or Encoding.*.GetString() handle \0 well
static int StringLength(byte[] buffer, int startIndex = 0)
{
    int strlen = 0;
    while
    (
        (startIndex + strlen + 1) < buffer.Length // Make sure incrementing won't break any bounds
        && buffer[startIndex + strlen] != 0       // The typical null terimation check
    )
    {
        ++strlen;
    }
    return strlen;
}

// This is messy, but I haven't found a built-in way in c# that guarentees null termination
public static string ParseBytes(byte[] buffer, out int strlen, int startIndex = 0)
{
    strlen = StringLength(buffer, startIndex);
    byte[] c_str = new byte[strlen];
    Array.Copy(buffer, startIndex, c_str, 0, strlen);
    return Encoding.UTF8.GetString(c_str);
}

سبب startIndex كان في المثال الذي كنت أعمل عليه على وجه التحديد ، وكنت بحاجة إلى تحليل byte[] كصفيف من السلاسل الفارغة التي تم إنهاؤها. يمكن تجاهلها بأمان في الحالة البسيطة

2
Assimilater

يمكن استخدام فئة BitConverter لتحويل byte[] إلى string.

var convertedString = BitConverter.ToString(byteAttay);

وثائق BitConverter class يمكن أن تكون fount on MSDN

2
Sagar

سيكون Linq أحادي الاتجاه لتحويل صفيف بايت byteArrFilename من ملف إلى سلسلة ascii خالصة خالصة من النمط C سيكون هذا: مفيد لقراءة أشياء مثل جداول فهرس الملفات في تنسيقات الأرشيف القديمة.

String filename = new String(byteArrFilename.TakeWhile(x => x != 0)
                              .Select(x => x < 128 ? (Char)x : '?').ToArray());

يمكنني استخدام '?' كأحرف افتراضية لأي شيء ليس ascii خالصًا هنا ، ولكن يمكن تغيير ذلك بالطبع. إذا كنت تريد التأكد من قدرتك على اكتشافه ، فما عليك سوى استخدام '\0' بدلاً من ذلك ، لأن TakeWhile في البداية يضمن أن السلسلة التي تم إنشاؤها بهذه الطريقة لا يمكن أن تحتوي على قيم '\0' من مصدر الإدخال.

2
Nyerguds

hier هي نتيجة حيث لم يكن لديك عناء مع الترميز. لقد استخدمتها في فئة الشبكة وأرسل كائنات ثنائية كسلسلة بها.

        public static byte[] String2ByteArray(string str)
        {
            char[] chars = str.ToArray();
            byte[] bytes = new byte[chars.Length * 2];

            for (int i = 0; i < chars.Length; i++)
                Array.Copy(BitConverter.GetBytes(chars[i]), 0, bytes, i * 2, 2);

            return bytes;
        }

        public static string ByteArray2String(byte[] bytes)
        {
            char[] chars = new char[bytes.Length / 2];

            for (int i = 0; i < chars.Length; i++)
                chars[i] = BitConverter.ToChar(bytes, i * 2);

            return new string(chars);
        }
1
Marco Pardo

بالإضافة إلى الإجابة المحددة ، إذا كنت تستخدم .NET35 أو .NET35 CE ، فيتعين عليك تحديد فهرس البايت الأول لفك التشفير ، وعدد البايتات المطلوب فك تشفيرها:

string result = System.Text.Encoding.UTF8.GetString(byteArray,0,byteArray.Length);
0
The One

جرب هذا:

string myresult = System.Text.Encoding.UTF8.GetString(byteArray);
0
Bill