14

So I was using BitConverter.GetBytes() to convert uint32 to byte[], but my the order in the array seems to be backwards. http://msdn.microsoft.com/en-us/library/1184xdy4.aspx (shows that it's byte[] seems to be little endian).

Is there a better way handle this than just using linq to reverse the byte arrays?

2
  • I guess that's where I'm confused though since BitConverter.IsLittleEndian returns false, but BitConverter.GetBytes() returns little endian arrays. Commented Aug 3, 2010 at 17:07
  • If this is Windows, BitConverter.IsLittleEndian returning false is clearly a bug, since x86 and x86-64 processors are Little Endian. Commented Aug 5, 2010 at 15:16

5 Answers 5

7

Array.Reverse to change the endianess.

Sign up to request clarification or add additional context in comments.

Comments

7

If you are going to be moving between platform architectures simply reversing the array might be correct on one platform, but fail on a platform that is already using big endian.

You use the IPAddress.HostToNetworkOrder functions, which will ensure that the data is always in network order (big endian).

uint number = 234234233;
uint bigEndian = (uint)IPAddress.HostToNetworkOrder((int)number);
byte[] b = BitConverter.GetBytes(bigEndian);

4 Comments

Thank you. It is faster than Array.Reverse. But I had troubles with types while not wrote code like this: var buffer = BitConverter.GetBytes((uint)IPAddress.HostToNetworkOrder((int)i));
@Geograph, what trouble did you have? It might be worth creating a dedicated question for this, that way you can provide a more complete example and details.
Your original example can't compile with error "CS0266 Cannot implicitly convert type 'long' to 'uint'. An explicit conversion exists (are you missing a cast?)"
@Geograph, I see. Yes for this to work correctly you would need to cast number to int, to get a int sized result back. I will update the sample, thanks.
5

Microsoft discusses the little-endian / big-endian issue with the GetBytes() method on the documentation page for BitConverter.

Comments

3

So I figured out a big part of my confusion is related to this: IsLittleEndian field reports false, but it must be Little-Endian?

What I ended up doing was wrapping all the BitConverter calls with call that took an extra parameter to specifiy endianness, then added a function that gets called to check to see if the bytes need to be revered.

public static class BitEndianConverter
{
    public static byte[] GetBytes(bool value, bool littleEndian)
    {
        return ReverseAsNeeded(BitConverter.GetBytes(value), littleEndian);
    }

    public static byte[] GetBytes(char value, bool littleEndian)
    {
        return ReverseAsNeeded(BitConverter.GetBytes(value), littleEndian);
    }
    public static byte[] GetBytes(double value, bool littleEndian)
    {
        return ReverseAsNeeded(BitConverter.GetBytes(value), littleEndian);
    }
    public static byte[] GetBytes(float value, bool littleEndian)
    {
        return ReverseAsNeeded(BitConverter.GetBytes(value), littleEndian);
    }
    public static byte[] GetBytes(int value, bool littleEndian)
    {
        return ReverseAsNeeded(BitConverter.GetBytes(value), littleEndian);
    }
    public static byte[] GetBytes(long value, bool littleEndian)
    {
        return ReverseAsNeeded(BitConverter.GetBytes(value), littleEndian);
    }
    public static byte[] GetBytes(short value, bool littleEndian)
    {
        return ReverseAsNeeded(BitConverter.GetBytes(value), littleEndian);
    }
    public static byte[] GetBytes(uint value, bool littleEndian)
    {
        return ReverseAsNeeded(BitConverter.GetBytes(value), littleEndian);
    }
    public static byte[] GetBytes(ulong value, bool littleEndian)
    {
        return ReverseAsNeeded(BitConverter.GetBytes(value), littleEndian);
    }
    public static byte[] GetBytes(ushort value, bool littleEndian)
    {
        return ReverseAsNeeded(BitConverter.GetBytes(value), littleEndian);
    }

    private static byte[] ReverseAsNeeded(byte[] bytes, bool wantsLittleEndian)
    {
        if (wantsLittleEndian == BitConverter.IsLittleEndian)
            return bytes;
        else
            return (byte[])bytes.Reverse().ToArray();
    }
}

1 Comment

I copied this class, it works well and is more intuitive and readable than other solutions. I was wondering if it makes sense or if it is possible to make GetBytes generic ? something like public static byte[] GetBytes<T>(T value, bool littleEndian)...
1

Following is a method to always get big endian byte array quickly.

    public static byte[] GetBigEndianBytes(UInt32 val, bool isLittleEndian)
    {
        UInt32 bigEndian = val;
        if (isLittleEndian)
        {
            bigEndian = (val & 0x000000FFU) << 24 | (val & 0x0000FF00U) << 8 |
                 (val & 0x00FF0000U) >> 8 | (val & 0xFF000000U) >> 24;
        }
        return BitConverter.GetBytes(bigEndian);
    }

This overload can be handy, although care must be taken when working across machines with different endian-nesses.

    public static byte[] GetBigEndianBytes(UInt32 val)
    {
        return GetBigEndianBytes(val, BitConverter.IsLittleEndian);
    }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.