byte[] to hex string [duplicate]

2018-12-31 18:18发布

This question already has an answer here:

How do I convert a byte[] to a string? Every time I attempt it, I get

System.Byte[]

instead of the value.

Also, how do I get the value in Hex instead of a decimal?

标签: c# string hex
19条回答
泛滥B
2楼-- · 2018-12-31 18:58

There is a built in method for this:

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

string hex = BitConverter.ToString(data);

Result: 01-02-04-08-10-20

If you want it without the dashes, just remove them:

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

Result: 010204081020

If you want a more compact representation, you can use Base64:

string base64 = Convert.ToBase64String(data);

Result: AQIECBAg

查看更多
皆成旧梦
3楼-- · 2018-12-31 18:58

I like using extension methods for conversions like this, even if they just wrap standard library methods. In the case of hexadecimal conversions, I use the following hand-tuned (i.e., fast) algorithms:

public static string ToHex(this 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 + 0x37 + 0x20 : b + 0x30);

        b = ((byte)(bytes[bx] & 0x0F));
        c[++cx]=(char)(b > 9 ? b + 0x37 + 0x20 : b + 0x30);
    }

    return new string(c);
}

public static byte[] HexToBytes(this string str)
{
    if (str.Length == 0 || str.Length % 2 != 0)
        return new byte[0];

    byte[] buffer = new byte[str.Length / 2];
    char c;
    for (int bx = 0, sx = 0; bx < buffer.Length; ++bx, ++sx)
    {
        // Convert first half of byte
        c = str[sx];
        buffer[bx] = (byte)((c > '9' ? (c > 'Z' ? (c - 'a' + 10) : (c - 'A' + 10)) : (c - '0')) << 4);

        // Convert second half of byte
        c = str[++sx];
        buffer[bx] |= (byte)(c > '9' ? (c > 'Z' ? (c - 'a' + 10) : (c - 'A' + 10)) : (c - '0'));
    }

    return buffer;
}
查看更多
浅入江南
4楼-- · 2018-12-31 18:58

Very fast extension methods (with reversal):

public static class ExtensionMethods {
    public static string ToHex(this byte[] data) {
        return ToHex(data, "");
    }
    public static string ToHex(this byte[] data, string prefix) {
        char[] lookup = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
        int i = 0, p = prefix.Length, l = data.Length;
        char[] c = new char[l * 2 + p];
        byte d;
        for(; i < p; ++i) c[i] = prefix[i];
        i = -1;
        --l;
        --p;
        while(i < l) {
            d = data[++i];
            c[++p] = lookup[d >> 4];
            c[++p] = lookup[d & 0xF];
        }
        return new string(c, 0, c.Length);
    }
    public static byte[] FromHex(this string str) {
        return FromHex(str, 0, 0, 0);
    }
    public static byte[] FromHex(this string str, int offset, int step) {
        return FromHex(str, offset, step, 0);
    }
    public static byte[] FromHex(this string str, int offset, int step, int tail) {
        byte[] b = new byte[(str.Length - offset - tail + step) / (2 + step)];
        byte c1, c2;
        int l = str.Length - tail;
        int s = step + 1;
        for(int y = 0, x = offset; x < l; ++y, x += s) {
            c1 = (byte)str[x];
            if(c1 > 0x60) c1 -= 0x57;
            else if(c1 > 0x40) c1 -= 0x37;
            else c1 -= 0x30;
            c2 = (byte)str[++x];
            if(c2 > 0x60) c2 -= 0x57;
            else if(c2 > 0x40) c2 -= 0x37;
            else c2 -= 0x30;
            b[y] = (byte)((c1 << 4) + c2);
        }
        return b;
    }
}

Beats all the others in the speed test above:

=== Long string test
BitConvertReplace calculation Time Elapsed 2415 ms
StringBuilder calculation Time Elapsed 5668 ms
LinqConcat calculation Time Elapsed 11826 ms
LinqJoin calculation Time Elapsed 9323 ms
LinqAgg calculation Time Elapsed 7444 ms
ToHexTable calculation Time Elapsed 1028 ms
ToHexAcidzombie calculation Time Elapsed 1035 ms
ToHexPatrick calculation Time Elapsed 814 ms
ToHexKurt calculation Time Elapsed 1604 ms
ByteArrayToHexString calculation Time Elapsed 1330 ms

=== Many string test
BitConvertReplace calculation Time Elapsed 2238 ms
StringBuilder calculation Time Elapsed 5393 ms
LinqConcat calculation Time Elapsed 9043 ms
LinqJoin calculation Time Elapsed 9131 ms
LinqAgg calculation Time Elapsed 7324 ms
ToHexTable calculation Time Elapsed 968 ms
ToHexAcidzombie calculation Time Elapsed 969 ms
ToHexPatrick calculation Time Elapsed 956 ms
ToHexKurt calculation Time Elapsed 1547 ms
ByteArrayToHexString calculation Time Elapsed 1277 ms

查看更多
浅入江南
5楼-- · 2018-12-31 18:59

As others have said it depends on the encoding of the values in the byte array. Despite this you need to be very careful with this sort of thing or you may try to convert bytes that are not handled by the chosen encoding.

Jon Skeet has a good article about encoding and unicode in .NET. Recommended reading.

查看更多
伤终究还是伤i
6楼-- · 2018-12-31 19:02

Just to add one more answer to the pile, there is a System.Runtime.Remoting.Metadata.W3cXsd2001.SoapHexBinary class that I've used which can convert bytes to and from hex:

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

Not sure how it compares (benchmark) to other implementations, but IMO it is pretty simple -- especially for converting from hex back into bytes.

查看更多
路过你的时光
7楼-- · 2018-12-31 19:04

You combine LINQ with string methods:

string hex = string.Join("",
  bin.Select(
    bin => bin.ToString("X2")
      ).ToArray());
查看更多
登录 后发表回答