0

I want to convert a Byte array as fast as possible to a Hex String.

So through my previous question, I found the following code:

private static readonly uint[] _lookup32 = CreateLookup32();

    private static uint[] CreateLookup32()
    {
        var result = new uint[256];
        for (int i = 0; i < 256; i++)
        {
            string s = i.ToString("X2");
            result[i] = ((uint)s[0]) + ((uint)s[1] << 16);
        }
        return result;
    }

    private static string ByteArrayToHexViaLookup32(byte[] bytes)
    {
        var lookup32 = _lookup32;
        var result = new char[bytes.Length * 2];
        for (int i = 0; i < bytes.Length; i++)
        {
            var val = lookup32[bytes[i]];
            result[2 * i] = (char)val;
            result[2 * i + 1] = (char)(val >> 16);
        }
        return new string(result);
    }

This works great but the Issue with it is that the output string looks like this:

output: 0F42000AAD24120024
but i need it like this: 0F 42 00 0A AD 24 12 00 24

As my coding knowledge is kinda meh on "cryptic" looking algorithms I don't know where and how to add code so it would add a blank space between each 2 Bytes - (Hexoutputstring + " ") to it.

I could loop trough the string and add every 2 charackters a blank space but that would hugely increase the amount of time it needs to give me a useful results as appending strings is slow.

Could someone help me with the code above? Thanks you :)

  • What is `_lookup32`? – Jonathan Wood Oct 27 '21 at 20:10
  • @JonathanWood it is declared in provided code. – Guru Stron Oct 27 '21 at 20:12
  • Does this answer your question? [How do you convert a byte array to a hexadecimal string, and vice versa?](https://stackoverflow.com/questions/311165/how-do-you-convert-a-byte-array-to-a-hexadecimal-string-and-vice-versa). There are many possible answers in that question. One of them compares the speed of all of the candidates – Flydog57 Oct 27 '21 at 20:14
  • @Flydog57 he is just asking how to put spaces between the hex values – Nigel Oct 27 '21 at 20:17
  • Wouldn't that simply require that `var result = new char[bytes.Length*3];` and then adding `result[2 * i + 2] = ' ';` and stripping off the last byte before converting it to a string (or, if it's easier, sticking the space before each hex pair and skipping the first char). Or, making the array 1 character shorter, prepending the char, but skipping th pre-pend on the first time through the loop. Much like @nigelbess's answer – Flydog57 Oct 27 '21 at 21:22

3 Answers3

3
    private static string ByteArrayToHexViaLookup32(byte[] bytes)
    {
        var lookup32 = _lookup32;
        var byteCount = bytes.Length;
        var result = new char[3* byteCount - 1];
        for (int i = 0; i < byteCount; i++)
        {
            var val = lookup32[bytes[i]];
            int index = 3 * i;
            result[index] = (char)val;
            result[index + 1] = (char)(val >> 16);
            if (i < byteCount - 1) result[index + 2] = ' ';
        }
        return new string(result);
    }
Nigel
  • 2,961
  • 1
  • 14
  • 32
-1

If performance is one of your main concerns, I would approach it something like this:

private static readonly char[] digits = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };

private static string ByteArrayToHexViaLookup32(byte[] bytes)
{
    char[] buffer = new char[bytes.Length * 3];
    
    int index = 0;
    for (int i = 0; i < bytes.Length; i++)
    {
        if (index > 0)
            buffer[index++] = ' ';

        buffer[index++] = digits[(bytes[i] >> 4) & 0xf];
        buffer[index++] = digits[bytes[i] & 0xf];
    }
    
    return new string(buffer, 0, index);
}

The following version doesn't require any lookup array, but I'm not sure if it's as fast.

private static string ByteArrayToHexViaLookup32(byte[] bytes)
{
    char[] buffer = new char[bytes.Length * 3];

    int index = 0;
    for (int i = 0; i < bytes.Length; i++)
    {
        if (index > 0)
            buffer[index++] = ' ';

        buffer[index++] = GetDigit((bytes[i] >> 4) & 0xf);
        buffer[index++] = GetDigit(bytes[i] & 0xf);
    }

    return new string(buffer, 0, index);
}

private char GetDigit(int value)
{
    if (value < 10)
        return (char)('0' + value);
    return (char)('7' + value);
}

Both versions insert a space between bytes.

Jonathan Wood
  • 65,341
  • 71
  • 269
  • 466
-1
private static string ByteArrayToStringHex(byte[] bytes)
    {
        string hexValue = BitConverter.ToString(bytes);
        hexValue = hexValue.Replace("-", " ");

        return hexValue;
    }

I think it results the same values as which you want

Kom Pe
  • 35
  • 5