UTF-8 බයිට් [] නූල් බවට පරිවර්තනය කරන්නේ කෙසේද?


949

UTF-8byte[] අඩංගු බව මා දන්නා ගොනුවකින් පටවන ලද අරාවක් මා සතුව ඇත .

සමහර නිදොස් කිරීමේ කේතයක, මට එය නූලකට පරිවර්තනය කළ යුතුය. මෙය සිදු කරන එක් ලයිනර් එකක් තිබේද?

ආවරණ යටතේ එය වෙන් කිරීමක් හා මතක සටහනක් පමණක් විය යුතුය , එබැවින් එය ක්‍රියාත්මක නොකළද එය කළ හැකි විය යුතුය.


6
"නිකම්ම වෙන් කිරීමක් හා මතක සටහනක් විය යුතුය": .NET නූල UTF-16 කේතනය කර ඇති නිසා එය නිවැරදි නොවේ. යුනිකෝඩ් අක්ෂරයක් එක් යූටීඑෆ් -8 කේත ඒකකයක් හෝ එක් යූටීඑෆ් -16 කේත ඒකකයක් විය හැකිය. තවත් එකක් UTF-8 කේත ඒකක දෙකක් හෝ එක් UTF-16 කේත ඒකකයක් විය හැකිය, තවත් එකක් UTF-8 කේත ඒකක තුනක් හෝ එක් UTF-16 කේත ඒකකයක් විය හැකිය, තවත් එකක් UTF-8 කේත ඒකක හතරක් හෝ UTF-16 කේත ඒකක දෙකක් විය හැකිය. . මතක සටහනක් පුළුල් කළ හැකි නමුත් එය UTF-8 සිට UTF-16 පරිවර්තනය දක්වා හැසිරවිය නොහැක.
ටොම් බ්ලොජට්

Answers:


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

13
එය ශුන්‍ය අවසන් නූල් හසුරුවන්නේ කෙසේද?
maazza

15
නොදන්නා හේතුවක් නිසා එය කිසිසේත් සිදු නොවේ. මම ඒකට කතා කරනවා වගේ System.Text.Encoding.UTF8.GetString(buf).TrimEnd('\0');.
හායි-ඒන්ජල්

15
@ හායි-ඒන්ජල් නොදන්නා හේතුවක්? ශුන්‍ය-අවසන් වූ නූල් මෙතෙක් ජනප්‍රිය වීමට එකම හේතුව වූයේ සී භාෂාවයි - එය එසේ වූයේ අමුතු අමුතුකමක් නිසා පමණි (සීපීයූ උපදෙස් ශුන්‍ය-අවසන් කළ නූල් සමඟ කටයුතු කරයි). .NET භාවිතා කරන්නේ ශුන්‍ය-අවසන් කළ නූල් භාවිතා කරන කේතය සමඟ අන්තර් ක්‍රියා කරන විට ( අවසානයේදී අතුරුදහන් වන) පමණි. නූලකට NUL අක්ෂර අඩංගු වීම සඳහා එය සම්පූර්ණයෙන්ම වලංගු වේ. ඇත්ත වශයෙන්ම, ASCII හි ශූන්‍ය ලෙස අවසන් කරන ලද නූල් අක්‍රීය වී ඇති අතර (ඔබ පළමු ශුන්‍ය බයිට් ලබා ගන්නා තෙක් ගොඩනඟන්න), UTF-8 ඇතුළු අනෙකුත් කේතීකරණ එතරම් සරල නැත.
Luaan

4
යූටීඑෆ් -8 හි එක් ලස්සන ලක්ෂණයක් වන්නේ කෙටි අනුක්‍රමයක් කිසි විටෙකත් දිගු අනුක්‍රමයක පසු විපරමක් නොවන බවයි. එබැවින් ශුන්‍ය ලෙස අවසන් කරන ලද UTF-8 නූල සරල ය.
ප්ලග්වොෂ්

11
හොඳයි, වාසනාව එය සතුව ඇසිඅයි නොමැති නම් එය ඉවත් කිරීම. Convert.ToBase64String භාවිතා කරන්න.
එරික් බර්ග්ස්ටෙඩ්

330

මෙම පරිවර්තනය සිදු කිරීම සඳහා අවම වශයෙන් වෙනස් ආකාර හතරක් ඇත.

  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

7
එය සම්බන්ධ කරන්න:var decBytes2 = str.Split('-').Select(ch => Convert.ToByte(ch, 16)).ToArray();
drtf

26

ඔබ කේතන ක්‍රමය නොදන්නා විට බයිට් අරා සිට නූල් බවට පරිවර්තනය කිරීම සඳහා පොදු විසඳුමක්:

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

3
නමුත් මෙය උපකල්පනය කරන්නේ බයිට් ප්‍රවාහයේ කේතනය කරන BOM එකක් හෝ එය UTF-8 හි ඇති බවයි. නමුත් ඔබට කෙසේ හෝ එන්කෝඩින් සමඟ එය කළ හැකිය. ඔබ කේතන ක්‍රමය නොදන්නා විට එය ගැටලුව ඉන්ද්‍රජාලිකව විසඳන්නේ නැත.
සෙබස්තියන් සැන්ඩර්

13

අර්ථ දැක්වීම:

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

භාවිතා කිරීම:

string result = input.ConvertByteToString();

9

A ට පරිවර්තනය byte[]කිරීම stringසරල බව පෙනේ, නමුත් ඕනෑම ආකාරයක කේතන ක්‍රමයක් මඟින් ප්‍රතිදාන නූල අවුල් විය හැක. මෙම කුඩා කාර්යය කිසිදු අනපේක්ෂිත ප්‍රති results ල නොමැතිව ක්‍රියා කරයි:

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

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

    return response;
}

මම Convert.FromBase64String සමඟ එය ඉවත් කළ විට ඔබේ ක්‍රමය භාවිතා කරමින් මට System.FormatException ලැබුණි.
එරික් බර්ග්ස්ටෙඩ්

@ ඇන්ඩ rew ජේ ඔබට පින්තූර වලින් භාවිතා කළ විශාල බයිට් අරා එකක් තිබේ නම් ගණනය කිරීමට පවා මෙය අවශ්‍ය වේ.
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));

නමුත් යූටීඑෆ් -8 මෙතික්ස් නොවේද?
david.pfx

1
UnicodeEncodingයනු නරකම පන්තියේ නමයි; යුනිකෝඩ් යනු කිසිසේත් කේතන ක්‍රමයක් නොවේ. එම පන්තිය ඇත්ත වශයෙන්ම UTF-16 වේ. පුංචි එන්ඩියන් අනුවාදය, මම හිතන්නේ.
නයර්ගුඩ්ස්


3

BitConverterබවට පරිවර්ථනය කිරිමට පන්ති භාවිතා කළ හැක byte[]සඳහා string.

var convertedString = BitConverter.ToString(byteAttay);

ලේඛනගත BitConverterපන්තිය මත fount විය හැකි MSDN හි


1
මෙය බයිට් අරාව එක් එක් බයිටය නියෝජනය කරන ෂඩාස්රාකාර නූලක් බවට පරිවර්තනය කරයි, එය සාමාන්‍යයෙන් බයිට් නූල් බවට පරිවර්තනය කිරීමේදී ඔබට අවශ්‍ය දේ නොවේ. ඔබ එසේ කරන්නේ නම්, එය තවත් ප්‍රශ්නයකි, උදාහරණයක් ලෙස බලන්න ඔබ බයිට් අරාව ෂඩාස්රාකාර සංගීතයට පරිවර්තනය කරන්නේ කෙසේද, සහ අනෙක් අතට? .
කෝඩ්කාස්ටර්

OP ඇසූ දේ නොවේ
ශීත

2

byteArrFilenameගොනුවක සිට කියවන ලද බයිට් අරා පිරිසිදු ascii C- ශෛලියේ ශුන්‍ය-අවසන් කරන ලද නූලක් බවට පරිවර්තනය කිරීම සඳහා ලින්ක් වන්-ලයිනර් මෙය වනු ඇත: පැරණි සංරක්ෂිත ආකෘතිවල ගොනු දර්ශක වගු වැනි දේවල් කියවීමට පහසුය.

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

මම '?'මෙහි පිරිසිදු ascii නොවන ඕනෑම දෙයක් සඳහා පෙරනිමි වර්‍ගයක් ලෙස භාවිතා කරමි , නමුත් එය වෙනස් කළ හැකිය. ඔබට එය හඳුනාගත හැකි බවට සහතික වීමට අවශ්‍ය නම්, '\0'ඒ වෙනුවට භාවිතා කරන්න, TakeWhileආරම්භයේදීම මේ ආකාරයෙන් සාදන ලද '\0'නූලකට ආදාන ප්‍රභවයෙන් අගයන් අඩංගු විය නොහැකි බව සහතික කරයි .


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)යනු ශුන්‍ය අවසන් කිරීමේ ගැටළුව විසඳීමට ඉක්මන් හා පහසු ක්‍රමයකි.
නයර්ගුඩ්ස්

1

හයර් යනු ඔබට කේතන ක්‍රමයට කරදර වීමට සිදු නොවූ ප්‍රති result ලයකි. මම එය මගේ ජාල පන්තියේ භාවිතා කර ද්විමය වස්තු ඒ සමඟ නූල් ලෙස යවමි.

        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 අතර වෙනසක් ගැන පමණි .

පසුගිය සතියේ, මගේ රැකියාවේදී, මට BOM සමඟ CSV ලිපිගොනු සහ වෙනත් UVF-8 (BOM නොමැතිව) සමඟ ප්‍රතිදානය කරන එක් ක්‍රියාකාරීත්වයක් වර්ධනය කළ යුතුය, සෑම CSV ලිපිගොනු කේතීකරණ වර්ගයක්ම ප්‍රමිතිගත නොවන API මඟින් පරිභෝජනය කරනු ඇත. API BOM සමඟ UTF-8 කියවන අතර අනෙක් API BOM නොමැතිව කියවනු ලැබේ. මෙම සංකල්පය පිළිබඳ යොමු කිරීම් ගවේෂණය කිරීමට මට අවශ්‍යය, " BOM නොමැතිව UTF-8 සහ UTF-8 අතර ඇති වෙනස කුමක්ද? " මගේ ප්‍රවේශය ගොඩනැගීම සඳහා පිටාර ගැලීමේ සාකච්ඡාව සහ මෙම විකිපීඩියා සබැඳිය " බයිට් ඇණවුම් සලකුණ " කියවීම .

අවසාන වශයෙන්, යූටීඑෆ් -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);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.