问题
I recently came across the issue of needing to frequently (& easily) convert & extract bytes from a BigEndian byte array that was being received over TCP. For those unfamiliar with Big/Little Endian, the short version is that each number was sent as MSB then LSB.
When processing and extracting values from the byte array using the default BitConverter on a Little Endian system (read: just about any C#/windows machine), this is a problem.
回答1:
Here are some handy extension methods that I created in my project that I thought I would share with fellow readers. The trick here is to only reverse the bytes required for the requested data size.
As a bonus, the byte[ ] extension methods makes the code tidy (in my opinion).
Comments & improvements are welcome.
Syntax to use:
var bytes = new byte[] { 0x01, 0x02, 0x03, 0x04 };
var uint16bigend = bytes.GetUInt16BigE(2); // MSB-LSB ... 03-04 = 772
var uint16bitconv = bytes.GetUInt16(2); // LSB-MSB ... 04-03 = 1027
Here is the class with the initial set of extensions. Easy for readers to extend & customize:
public static class BitConverterExtensions
{
public static UInt16 GetUInt16BigE(this byte[] bytes, int startIndex)
{
return BitConverter.ToUInt16(bytes.Skip(startIndex).Take(2).Reverse().ToArray(), 0);
}
public static UInt32 GetUInt32BigE(this byte[] bytes, int startIndex)
{
return BitConverter.ToUInt32(bytes.Skip(startIndex).Take(4).Reverse().ToArray(), 0);
}
public static Int16 GetInt16BigE(this byte[] bytes, int startIndex)
{
return BitConverter.ToInt16(bytes.Skip(startIndex).Take(2).Reverse().ToArray(), 0);
}
public static Int32 GetInt32BigE(this byte[] bytes, int startIndex)
{
return BitConverter.ToInt32(bytes.Skip(startIndex).Take(4).Reverse().ToArray(), 0);
}
public static UInt16 GetUInt16(this byte[] bytes, int startIndex)
{
return BitConverter.ToUInt16(bytes, startIndex);
}
public static UInt32 GetUInt32(this byte[] bytes, int startIndex)
{
return BitConverter.ToUInt32(bytes, startIndex);
}
public static Int16 GetInt16(this byte[] bytes, int startIndex)
{
return BitConverter.ToInt16(bytes, startIndex);
}
public static Int32 GetInt32(this byte[] bytes, int startIndex)
{
return BitConverter.ToInt32(bytes, startIndex);
}
}
回答2:
You might want to look at using an endian-aware BinaryReader/BinaryWriter implemention. Here are links to some:
Jon Skeet's answer to the question, BinaryWriter Endian issue
Anculus.Core.IO has an endian-aware
BinaryReader
,BinaryWriter
andBitConverter
: https://code.google.com/p/libanculus-sharp/source/browse/trunk/src/Anculus.Core/IO/?r=227The Iso-Parser project (parser for parsing ISO disk images) has an endian-aware BitConverter
Rabbit MQ (Rabbit Message Queue) has an big-endian BinaryReader and BinaryWriter on Github at https://github.com/rabbitmq/rabbitmq-dotnet-client.
来源:https://stackoverflow.com/questions/24004507/helpful-byte-array-extensions-to-handle-bigendian-data