0

我正在寻找一个帮助类,它可以修改字节数组中的特定位,其 API 类似于以下内容:

void Set(int startPos, int lengthInBits, int value) {
  // Set the bits starting at startPos to the binary representation of value
  // Error if the binary representation of value is too long (ie. exceeds lengthInBits)
}

目的是能够将任意长度的特定值放入一个字节数组中——一些值的长度小于一个字节,另一些则更多,还有一些会“跨越”字节。

我看过ByteBuffer但这似乎有点太高级了,只能处理整个字节,并将 int 和 short 转换为多个字节,而不是让你选择它们的最大位数。

我还查看了BitSet,但这次它似乎有点太低级了,因为它只能在单个位级别上工作(尽管我可能会使用它作为使用上述 API 构建某些东西的起点)。

在 Stack Overflow 上还有一个类似的老问题,主要与有符号/无符号位的使用有关,但图中的数据结构是我试图构建的那种东西(发送给外部客户端的消息),并且我想尽可能多地隐藏位移复杂性。

4

2 回答 2

0

这并不难。也许这可以帮助您作为起点:

ByteBuffer data;

int getBits(int bitOff, int bitSize)
{
  if(bitSize>32) throw new UnsupportedOperationException();
  final int mask= bitSize==32? -1: (1<<bitSize)-1;
  return (int)((data.getLong(bitOff>>>3) >>> (64-bitSize-(bitOff&7))) & mask);
}
void putBits(int bitOff, int bitSize, int intValue)
{
  final int byteOff=bitOff>>>3;
  bitOff -= byteOff<<3;
  final int shift = 64-bitSize-bitOff;
  long mask=Long.rotateLeft((-1L)<<bitSize, shift), lValue=intValue&0xffffffffL;
  data.putLong(byteOff, (lValue << shift) | (data.getLong(byteOff)&mask));
}
于 2013-10-28T14:52:27.637 回答
0

您可以扩展 java.util.BitSet,它已经处理了任意位数的存储。您需要添加的只是批量获取/设置操作:

public class BulkBitSet extends BitSet {

    public void bulkSet(int offset, int count, int data) {
        int ptr = offset + count;
        for (int i=0; i<count; ++i) {
            set(--ptr, (data & (1 << i)) == 0 ? false : true);
        }
    }

    public int bulkGet(int offset, int count) {
        int result = 0;
        for (int i=0; i<count; ++i) {
            result <<= 1;
            if (get(offset + i))
                result |= 1;
        }
        return result;
    }

}
于 2013-10-28T16:32:04.730 回答