Reputation: 3089
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?
Upvotes: 14
Views: 50565
Reputation: 53699
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);
Upvotes: 7
Reputation: 4422
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);
}
Upvotes: 1
Reputation: 3089
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();
}
}
Upvotes: 3
Reputation: 1696
Microsoft discusses the little-endian / big-endian issue with the GetBytes() method on the documentation page for BitConverter.
Upvotes: 5