我目前正在研究一种网络工具,它需要对特定协议进行解码/编码,该协议将字段打包到任意位置的密集位数组中.例如,协议的一部分使用3个字节来表示许多不同的字段:
Bit Position(s) Length (In Bits) Type
0 1 bool
1-5 5 int
6-13 8 int
14-22 9 uint
23 1 bool
Run Code Online (Sandbox Code Playgroud)
如您所见,其中一些字段跨越多个字节.许多(大多数)也比可能用于表示它们的内置类型短,例如第一个只有5位长的int字段.在这些情况下,目标类型的最高有效位(例如Int32或Int16)应填充为0以弥补差异.
我的问题是我很难处理这类数据.具体来说,我很难弄清楚如何有效地获取任意长度的位数组,用源缓冲区中的相应位填充它们,填充它们以匹配目标类型,并将填充的位数组转换为目标类型.在理想的世界中,我可以在上面的例子中使用字节[3]并调用类似的方法GetInt32(byte[] bytes, int startBit, int length).
我发现的最接近的东西是BitStream类,但它似乎希望单个值在字节/字边界上排列(并且类的半流/半索引访问约定使它变得有点混乱).
我自己的第一次尝试是使用BitArray类,但事实证明这有点笨拙.很容易将缓冲区中的所有位填充到一个大的BitArray,只将你想要的从源BitArray传输到一个新的临时BitArray,然后将其转换为目标值...但它似乎是错误的,而且非常耗时.
我现在正在考虑一个类如下的类,它引用(或创建)源/目标byte []缓冲区以及偏移量,并为某些目标类型提供get和set方法.棘手的部分是获取/设置值可能跨越多个字节.
class BitField
{
private readonly byte[] _bytes;
private readonly int _offset;
public BitField(byte[] bytes)
: this(bytes, 0)
{
}
public BitField(byte[] bytes, int offset)
{
_bytes = bytes;
_offset = offset;
}
public BitField(int size) …Run Code Online (Sandbox Code Playgroud)