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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.