Pythoneer
Pythoneer

Reputation: 107

How to convert a byte array of any size to ulong in C#?

Consider having various byte arrays of different lengths like:

byte[] a = new byte[]{0x6};
byte[] b = new byte[]{0x6, 0x33, 0x22};
byte[] c = new byte[]{0x6, 0x33, 0x22, 0x14, 0x47};

How to convert these byte arrays of, basically any size, except greater then 8 bytes, to ulong?

I'm aware of the BitConverter class in C#, but there you have always to provide exact number of bytes...

Upvotes: 0

Views: 2921

Answers (2)

Dmitrii Bychenko
Dmitrii Bychenko

Reputation: 186698

You can take two case into account: complete and incomplete data array. If you want to have BitConverter improved version:

public static ulong MyToUInt64(byte[] data) {
  if (null == data)
    throw new ArgumentNullException(nameof(data)); // or return 0

  if (data.Length >= sizeof(ulong)) // we have enough bytes (at least 8)
    return BitConverter.ToUInt64(data, 0);

  // padded version (8 bytes) of data array
  byte[] complete = new byte[sizeof(ulong)];

  for (int i = 0; i < data.Length; ++i) 
    if (BitConverter.IsLittleEndian) // we have two ways of padding
      complete[i] = data[i];
    else 
      complete[complete.Length - i - 1] = data[data.Length - i - 1];

  return BitConverter.ToUInt64(complete);
}

Upvotes: 0

canton7
canton7

Reputation: 42245

You can do this easily using for loops and bit shifting:

public static ulong BytesToUInt64(byte[] bytes)
{
    if (bytes == null)
        throw new ArgumentNullException(nameof(bytes));
    if (bytes.Length > 8)
        throw new ArgumentException("Must be 8 elements or fewer", nameof(bytes));

    ulong result = 0;
    for (int i = 0; i < bytes.Length; i++)
    {
        result |= (ulong)bytes[i] << (i * 8);
    }   
    
    return result;
}

See it on SharpLab.

We take the first element in the byte array, and combine it into result using a bitwise OR. We take the second element, shift it left 8 bits (so it sits just on top of the first element), and OR that in. And so on, for the remaining bytes.

Note that this puts the byte at index 0 in the least-significant position. You can fiddle with the indexing of bytes and the left shift to change this, if you need to.


You can also approach this by padding your byte array with 0's. Although less efficient on the face of it, it may still come out cheaper (and clearer) than the looping and bit-shifting above. See this question for details.

Upvotes: 5

Related Questions