如何将字节[]转换为字符串?每次我尝试,我都

系统。Byte []

而不是数值。

另外,我如何得到十六进制而不是小数的值?


当前回答

正如其他人所说,这取决于字节数组中值的编码方式。尽管如此,您还是需要非常小心地处理这类事情,否则您可能会尝试转换未被所选编码处理的字节。

Jon Skeet有一篇关于。net中的编码和unicode的好文章。推荐阅读。

其他回答

再向这个堆中添加一个答案,有一个System.Runtime.Remoting.Metadata.W3cXsd2001。SoapHexBinary类,我已经使用它可以转换字节和十六进制:

string hex = new SoapHexBinary(bytes).ToString();
byte[] bytes = SoapHexBinary.Parse(hex).Value;

不确定它与其他实现(基准)相比如何,但在我看来,它非常简单——特别是从十六进制转换回字节。

你必须知道以字节表示的字符串的编码,但是你可以说System.Text.UTF8Encoding.GetString(字节)或System.Text.ASCIIEncoding.GetString(字节)。(我是根据记忆做的,所以API可能不完全正确,但它非常接近。)

第二个问题的答案,请看这个问题。

我不经常把字节转换成十六进制所以我不知道有没有更好的方法,但这里有一种方法。

StringBuilder sb = new StringBuilder();
foreach (byte b in myByteArray)
    sb.Append(b.ToString("X2"));

string hexString = sb.ToString();

.Net5.0更新

感谢@antoninkriz的基准比较,我们可以看到Convert。到目前为止,ToHexString是明显的赢家

使用Convert.ToHexString以外的任何方法都是愚蠢的。在我看来,它在可读性、性能和安全性方面明显更胜一筹


剩下的是2012年4月10日之前的数据:

我想我应该尝试比较这里列出的每个方法的速度。我基于这个编写了速度测试代码。

结果是BitConverter+String。替换似乎比大多数其他简单的方法更快。但是可以通过像Nathan Moinvaziri的ByteArrayToHexString或Kurt的ToHex这样的算法来提高速度。

我还发现了一个有趣的字符串。连接和串。对于长字符串,Join比StringBuilder实现慢得多,但对于较短的数组也类似。可能是由于在较长的字符串上扩展StringBuilder,所以设置初始大小应该消除这种差异。

Took each bit of code from an answer here: BitConvertRep = Answer by Guffa, BitConverter and String.Replace (I'd recommend for most cases, [edit:] where you can't use Convert.ToHexString) StringBuilder = Answer by Quintin Robinson, foreach char StringBuilder.Append LinqConcat = Answer by Michael Buen, string.Concat of Linq built array LinqJoin = Answer by mloskot, string.Join of Linq built array LinqAgg = Answer by Matthew Whited, IEnumerable.Aggregate with StringBuilder ToHex = Answer by Kurt, sets chars in an array, using byte values to get hex ByteArrayToHexString = Answer by Nathan Moinvaziri, approx same speed as the ToHex above, and is probably easier to read (I'd recommend for speed, [edit:] where you can't use Convert.ToHexString) ToHexFromTable = Linked in answer by Nathan Moinvaziri, for me this is near the same speed as the above 2 but requires an array of 256 strings to always exist

With: LONG_STRING_LENGTH = 1000 * 1024; BitConvertRep calculation Time Elapsed 27,202 ms (fastest built in/simple) StringBuilder calculation Time Elapsed 75,723 ms (StringBuilder no reallocate) LinqConcat calculation Time Elapsed 182,094 ms LinqJoin calculation Time Elapsed 181,142 ms LinqAgg calculation Time Elapsed 93,087 ms (StringBuilder with reallocating) ToHex calculation Time Elapsed 19,167 ms (fastest) With: LONG_STRING_LENGTH = 100 * 1024;, Similar results BitConvertReplace calculation Time Elapsed 3431 ms StringBuilder calculation Time Elapsed 8289 ms LinqConcat calculation Time Elapsed 21512 ms LinqJoin calculation Time Elapsed 19433 ms LinqAgg calculation Time Elapsed 9230 ms ToHex calculation Time Elapsed 1976 ms With: int MANY_STRING_COUNT = 1000; int MANY_STRING_LENGTH = 1024; (Same byte count as first test but in different arrays) BitConvertReplace calculation Time Elapsed 25,680 ms StringBuilder calculation Time Elapsed 78,411 ms LinqConcat calculation Time Elapsed 101,233 ms LinqJoin calculation Time Elapsed 99,311 ms LinqAgg calculation Time Elapsed 84,660 ms ToHex calculation Time Elapsed 18,221 ms With: int MANY_STRING_COUNT = 2000; int MANY_STRING_LENGTH = 20; BitConvertReplace calculation Time Elapsed 1347 ms StringBuilder calculation Time Elapsed 3234 ms LinqConcat calculation Time Elapsed 5013 ms LinqJoin calculation Time Elapsed 4826 ms LinqAgg calculation Time Elapsed 3589 ms ToHex calculation Time Elapsed 772 ms

我使用的测试代码:

void Main()
{
    int LONG_STRING_LENGTH = 100 * 1024;
    int MANY_STRING_COUNT = 1024;
    int MANY_STRING_LENGTH = 100;

    var source = GetRandomBytes(LONG_STRING_LENGTH);

    List<byte[]> manyString = new List<byte[]>(MANY_STRING_COUNT);
    for (int i = 0; i < MANY_STRING_COUNT; ++i)
    {
        manyString.Add(GetRandomBytes(MANY_STRING_LENGTH));
    }

    var algorithms = new Dictionary<string,Func<byte[], string>>();
    algorithms["BitConvertReplace"] = BitConv;
    algorithms["StringBuilder"] = StringBuilderTest;
    algorithms["LinqConcat"] = LinqConcat;
    algorithms["LinqJoin"] = LinqJoin;
    algorithms["LinqAgg"] = LinqAgg;
    algorithms["ToHex"] = ToHex;
    algorithms["ByteArrayToHexString"] = ByteArrayToHexString;

    Console.WriteLine(" === Long string test");
    foreach (var pair in algorithms) {
        TimeAction(pair.Key + " calculation", 500, () =>
        {
            pair.Value(source);
        });
    }

    Console.WriteLine(" === Many string test");
    foreach (var pair in algorithms) {
        TimeAction(pair.Key + " calculation", 500, () =>
        {
            foreach (var str in manyString)
            {
                pair.Value(str);
            }
        });
    }
}

// Define other methods and classes here
static void TimeAction(string description, int iterations, Action func) {
    var watch = new Stopwatch();
    watch.Start();
    for (int i = 0; i < iterations; i++) {
        func();
    }
    watch.Stop();
    Console.Write(description);
    Console.WriteLine(" Time Elapsed {0} ms", watch.ElapsedMilliseconds);
}

//static byte[] GetRandomBytes(int count) {
//  var bytes = new byte[count];
//  (new Random()).NextBytes(bytes);
//  return bytes;
//}
static Random rand = new Random();
static byte[] GetRandomBytes(int count) {
    var bytes = new byte[count];
    rand.NextBytes(bytes);
    return bytes;
}


static string BitConv(byte[] data)
{
    return BitConverter.ToString(data).Replace("-", string.Empty);
}
static string StringBuilderTest(byte[] data)
{
    StringBuilder sb = new StringBuilder(data.Length*2);
    foreach (byte b in data)
        sb.Append(b.ToString("X2"));

    return sb.ToString();
}
static string LinqConcat(byte[] data)
{
    return string.Concat(data.Select(b => b.ToString("X2")).ToArray());
}
static string LinqJoin(byte[] data)
{
    return string.Join("",
        data.Select(
            bin => bin.ToString("X2")
            ).ToArray());
}
static string LinqAgg(byte[] data)
{
    return data.Aggregate(new StringBuilder(),
                               (sb,v)=>sb.Append(v.ToString("X2"))
                              ).ToString();
}
static string ToHex(byte[] bytes)
{
    char[] c = new char[bytes.Length * 2];

    byte b;

    for(int bx = 0, cx = 0; bx < bytes.Length; ++bx, ++cx)
    {
        b = ((byte)(bytes[bx] >> 4));
        c[cx] = (char)(b > 9 ? b - 10 + 'A' : b + '0');

        b = ((byte)(bytes[bx] & 0x0F));
        c[++cx] = (char)(b > 9 ? b - 10 + 'A' : b + '0');
    }

    return new string(c);
}
public static string ByteArrayToHexString(byte[] Bytes)
{
    StringBuilder Result = new StringBuilder(Bytes.Length*2);
    string HexAlphabet = "0123456789ABCDEF";

    foreach (byte B in Bytes)
        {
        Result.Append(HexAlphabet[(int)(B >> 4)]);
        Result.Append(HexAlphabet[(int)(B & 0xF)]);
        }

    return Result.ToString();
}

还有一个类似过程的答案,我还没有比较我们的结果。

有一个内置的方法:

byte[] data = { 1, 2, 4, 8, 16, 32 };

string hex = BitConverter.ToString(data);

结果:01-02-04-08-10-20

如果你想要没有破折号,只需删除它们:

string hex = BitConverter.ToString(data).Replace("-", string.Empty);

结果:010204081020

如果你想要一个更紧凑的表示,你可以使用Base64:

string base64 = Convert.ToBase64String(data);

结果:AQIECBAg