【发布时间】:2014-07-23 03:49:54
【问题描述】:
我最近遇到了需要从通过 TCP 接收的 BigEndian 字节数组中频繁(轻松地)转换和提取字节的问题。对于那些不熟悉 Big/Little Endian 的人来说,简短的版本是每个数字都以 MSB 然后 LSB 的形式发送。
在 Little Endian 系统(阅读:几乎任何 C#/windows 机器)上使用默认 BitConverter 从字节数组处理和提取值时,这是一个问题。
【问题讨论】:
我最近遇到了需要从通过 TCP 接收的 BigEndian 字节数组中频繁(轻松地)转换和提取字节的问题。对于那些不熟悉 Big/Little Endian 的人来说,简短的版本是每个数字都以 MSB 然后 LSB 的形式发送。
在 Little Endian 系统(阅读:几乎任何 C#/windows 机器)上使用默认 BitConverter 从字节数组处理和提取值时,这是一个问题。
【问题讨论】:
以下是我在项目中创建的一些方便的扩展方法,我认为我会与其他读者分享。这里的技巧是只反转请求的数据大小所需的字节。
作为奖励,byte[ ] 扩展方法使代码整洁(在我看来)。
欢迎提出意见和改进。
要使用的语法:
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
这是具有初始扩展集的类。便于读者扩展和定制:
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);
}
}
【讨论】:
您可能希望了解使用字节序感知的 BinaryReader/BinaryWriter 实现。以下是一些链接:
Anculus.Core.IO 具有字节序感知 BinaryReader、BinaryWriter 和 BitConverter:https://code.google.com/p/libanculus-sharp/source/browse/trunk/src/Anculus.Core/IO/?r=227
Iso-Parser 项目(用于解析 ISO 磁盘映像的解析器)有一个 endian-aware BitConverter
Rabbit MQ(Rabbit 消息队列)在 Github 上的 https://github.com/rabbitmq/rabbitmq-dotnet-client 上有一个大端 BinaryReader 和 BinaryWriter。
【讨论】: