UTF-8 बाइट [] को स्ट्रिंग में कैसे बदलें?


931

मेरे पास एक byte[]सरणी है जिसे एक फ़ाइल से लोड किया गया है जो मुझे ज्ञात है जिसमें UTF-8 है

कुछ डिबगिंग कोड में, मुझे इसे एक स्ट्रिंग में बदलने की आवश्यकता है। क्या कोई एक लाइनर है जो ऐसा करेगा?

कवर के तहत यह केवल एक आवंटन और एक ज्ञापन होना चाहिए , इसलिए भले ही इसे लागू न किया जाए, यह संभव होना चाहिए।


5
"सिर्फ एक आवंटन और एक ज्ञापन होना चाहिए": सही नहीं है क्योंकि .NET स्ट्रिंग UTF-16 एन्कोडेड है। एक यूनिकोड वर्ण एक UTF-8 कोड इकाई या एक UTF-16 कोड इकाई हो सकता है। एक और दो UTF-8 कोड इकाइयाँ या एक UTF-16 कोड इकाई हो सकती है, दूसरी तीन UTF-8 कोड इकाइयाँ या एक UTF-16 कोड इकाई हो सकती है, दूसरी चार UTF-8 कोड इकाइयाँ या दो UTF-16 कोड इकाइयाँ हो सकती हैं । एक ज्ञापन को चौड़ा करने में सक्षम हो सकता है, लेकिन यह UTF-8 को UTF-16 रूपांतरण में सक्षम नहीं कर पाएगा।
टॉम ब्लोगेट

जवाबों:


1468
string result = System.Text.Encoding.UTF8.GetString(byteArray);

13
यह कैसे नल समाप्त तार संभालती है?
मज्जा

14
अज्ञात कारण के लिए @maazza बिल्कुल नहीं। मैं इसे पसंद कर रहा हूं System.Text.Encoding.UTF8.GetString(buf).TrimEnd('\0');
हाय-एंजेल

15
@ हाय-एंजेल अज्ञात कारण? एकमात्र कारण कभी-कभी समाप्त हो जाने वाले तार लोकप्रिय हो गए थे सी भाषा - और यहां तक ​​कि केवल एक ऐतिहासिक विषमता के कारण (सीपीयू निर्देश जो शून्य-समाप्त तारों से निपटते थे)। .NET केवल शून्य-टर्मिनेटेड स्ट्रिंग्स का उपयोग करता है, जब कोड के साथ इंटरॉप करते हैं, जो शून्य-टर्मिनेटेड स्ट्रिंग्स (जो अंततः गायब हो रहे हैं ) का उपयोग करता है । यह NUL वर्णों को शामिल करने के लिए एक स्ट्रिंग के लिए पूरी तरह से मान्य है। और निश्चित रूप से, जबकि अशक्त-समाप्त तार एएससीआईआई में सरल मृत हैं (बस तब तक निर्माण करें जब तक आपको पहला शून्य बाइट न मिल जाए), यूटीएफ -8 सहित अन्य एनकोडिंग इतने सरल नहीं हैं।
लुआॅन

4
UTF-8 की सुंदर विशेषताओं में से एक यह है कि एक छोटा अनुक्रम कभी भी लंबे अनुक्रम का अनुवर्ती नहीं होता है। तो एक शून्य समाप्त UTF-8 स्ट्रिंग सरल है।
प्लग

10
अगर यह गैर-एससीआई है, तो खैर, अच्छी किस्मत इसे खोलना है। बस Convert.ToBase64String का उपयोग करें।
एरिक बर्गस्टेड

323

इस रूपांतरण को करने के कम से कम चार अलग-अलग तरीके हैं।

  1. एन्कोडिंग का गेटस्ट्रिंग
    , लेकिन आप मूल बाइट्स वापस पाने में सक्षम नहीं होंगे यदि उन बाइट्स में गैर-एएससीआईआई अक्षर हैं।

  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

7
LINQ it:var decBytes2 = str.Split('-').Select(ch => Convert.ToByte(ch, 16)).ToArray();
drtf

25

एन्कोडिंग को न जानने पर बाइट सरणी से स्ट्रिंग में बदलने का एक सामान्य समाधान:

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

3
लेकिन यह मानता है कि बाइट स्ट्रीम में या तो एन्कोडिंग BOM है या यह UTF-8 में है। लेकिन आप वैसे भी एन्कोडिंग के साथ भी ऐसा कर सकते हैं। जब आप एन्कोडिंग को नहीं जानते हैं तो यह समस्या का समाधान नहीं करता है।
सेबेस्टियन जेंडर

12

परिभाषा:

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

का उपयोग करते हुए:

string result = input.ConvertByteToString();

9

byte[]का रूपांतरण stringसरल प्रतीत होता है, लेकिन किसी भी तरह के एन्कोडिंग से आउटपुट स्ट्रिंग गड़बड़ाने की संभावना है। यह छोटा सा कार्य बिना किसी अप्रत्याशित परिणाम के काम करता है:

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

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

    return response;
}

जब मैंने इसे Convert.FromBase64String के साथ अनपैक किया तो मुझे आपके सिस्टम का उपयोग करके System.FormatException मिली।
एरिक बर्गस्टेड

@ एंड्रयूज यह गणना करने के लिए भी ले जाएगा यदि आपके पास चित्रों से उपयोग किए गए एक बड़े बाइट की तरह सरणी है।
16:38 पर user3841581

7

उपयोग (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;
    }

}

4

क्लास यूनिकोड इकोकोडिंग भी है, जो उपयोग में काफी सरल है:

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

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

लेकिन UTF-8 मैथिंक नहीं?
david.pfx

1
UnicodeEncodingअब तक का सबसे खराब वर्ग का नाम है; यूनिकोड बिल्कुल भी एन्कोडिंग नहीं है। वह वर्ग वास्तव में UTF-16 है। थोड़ा-सा एंडियन संस्करण, मुझे लगता है।
Nyerguds

3

वैकल्पिक रूप से:

 var byteStr = Convert.ToBase64String(bytes);

2

एक अलंकृत एक लाइनर एक बाइट सरणी byteArrFilenameको एक फ़ाइल से शुद्ध अस्की सी-शैली शून्य-टर्मिनेटेड स्ट्रिंग में परिवर्तित करने के लिए होगा: यह पुराने संग्रह प्रारूपों में फ़ाइल इंडेक्स टेबल जैसी चीजों को पढ़ने के लिए आसान है।

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

मैं '?'किसी भी चीज के लिए डिफॉल्ट चार के रूप में उपयोग करता हूं , यहां पर शुद्ध एसेसी नहीं है, लेकिन इसे बदला जा सकता है। यदि आप यह सुनिश्चित करना चाहते हैं कि आप इसका पता लगा सकते हैं, तो '\0'इसके बजाय इसका उपयोग करें , क्योंकि TakeWhileप्रारंभ में यह सुनिश्चित करता है कि इस तरह से निर्मित एक स्ट्रिंग '\0'में इनपुट स्रोत से मान शामिल नहीं हो सकते हैं ।


2

BitConvertera byte[]को रूपांतरित करने के लिए वर्ग का उपयोग किया जा सकता है string

var convertedString = BitConverter.ToString(byteAttay);

BitConverterवर्ग का प्रलेखन MSDN पर फव्वारा हो सकता है


1
यह बाइट सरणी को प्रत्येक बाइट का प्रतिनिधित्व करते हुए एक हेक्साडेसिमल स्ट्रिंग में परिवर्तित करता है, जो आम तौर पर बाइट्स को स्ट्रिंग में परिवर्तित करते समय आप क्या चाहते हैं। यदि आप करते हैं, तो यह एक और सवाल है, उदाहरण के लिए देखें कि आप बाइट ऐरे को हेक्साडेसिमल स्ट्रिंग में कैसे परिवर्तित करते हैं, और इसके विपरीत?
कोडकेस्टर

ओपी ने नहीं पूछा
विंटर

2

मेरे ज्ञान के लिए दिए गए उत्तरों में से कोई भी शून्य समाप्ति के साथ सही व्यवहार की गारंटी नहीं देता है। जब तक कोई मुझे अलग तरीके से नहीं दिखाता है तब तक मैंने निम्नलिखित तरीकों के साथ इसे संभालने के लिए अपना स्वयं का स्थिर वर्ग लिखा है:

// 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[]अशक्त समाप्त तार की एक सरणी के रूप में। साधारण मामले में इसे सुरक्षित रूप से अनदेखा किया जा सकता है


मेरा करता है, वास्तव में। byteArr.TakeWhile(x => x != 0)शून्य समाप्ति समस्या को हल करने का एक त्वरित और आसान तरीका है।
Nyerguds

1

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

एक नहीं था। लेकिन यह फ़ंक्शन हमारे कंपनी-नेटवर्क में बाइनरी ट्रांसमिशन के लिए उपयोग में है और अब तक 20TB फिर से सही तरीके से एन्कोड किए गए थे। तो मेरे लिए यह फ़ंक्शन काम करता है :)
मार्को पार्डो

1

चयनित उत्तर के लिए, यदि आप .NET35 या .NET35 CE का उपयोग कर रहे हैं, तो आपको पहले बाइट को डीकोड करने के लिए इंडेक्स निर्दिष्ट करना होगा, और बाइट की संख्या को डीकोड करना होगा:

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

0

इस कंसोल ऐप को आज़माएं:

static void Main(string[] args)
{
    //Encoding _UTF8 = Encoding.UTF8;
    string[] _mainString = { "Héllo World" };
    Console.WriteLine("Main String: " + _mainString);

    //Convert a string to utf-8 bytes.
    byte[] _utf8Bytes = Encoding.UTF8.GetBytes(_mainString[0]);

    //Convert utf-8 bytes to a string.
    string _stringuUnicode = Encoding.UTF8.GetString(_utf8Bytes);
    Console.WriteLine("String Unicode: " + _stringuUnicode);
}

0

मैंने इस पोस्ट पर कुछ उत्तर देखे और आधार ज्ञान को पूरा करना संभव माना, क्योंकि इसी समस्या को हल करने के लिए C # प्रोग्रामिंग में कई दृष्टिकोण हैं। केवल एक चीज जिस पर विचार किया जाना आवश्यक है, वह है BOM के साथ शुद्ध UTF-8 और UTF-8 के बीच अंतर

पिछले सप्ताह में, मेरी नौकरी पर, मुझे एक कार्यक्षमता विकसित करनी होगी जो CSV फ़ाइलों को BOM के साथ और अन्य CSV को शुद्ध UTF-8 (BOM के बिना) के साथ आउटपुट करती है, प्रत्येक CSV फ़ाइल एन्कोडिंग प्रकार को अलग-अलग गैर-मानक API API द्वारा खपाया जाएगा। एपीआई ने बीओएम के साथ यूटीएफ -8 पढ़ा और दूसरा एपीआई बिना बीओएम के पढ़ा। मुझे इस अवधारणा के संदर्भों पर शोध करने की ज़रूरत है, " मेरा दृष्टिकोण बनाने के लिए" यूटीएफ -8 और यूटीएफ -8 के बीच अंतर क्या है बिना बीओएम? "स्टैक ओवरफ्लो चर्चा और यह विकिपीडिया लिंक" बाइट ऑर्डर मार्क "।

अंत में, मेरा C # दोनों UTF-8 एन्कोडिंग प्रकार (BOM और शुद्ध के साथ) के लिए प्रोग्रामिंग करना इस उदाहरण की तरह होना चाहिए:

//for UTF-8 with B.O.M., equals shared by Zanoni (at top)
string result = System.Text.Encoding.UTF8.GetString(byteArray);

//for Pure UTF-8 (without B.O.M.)
string result = (new UTF8Encoding(false)).GetString(byteArray);
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.