将byte[]转换为BitSet

4
我正在尝试将一个字节数组转换为BitSet。以下是我使用的代码:
public BitSet byteToBits(byte[] bytearray){
    BitSet returnValue = new BitSet(bytearray.length*8);
    ByteBuffer  byteBuffer = ByteBuffer.wrap(bytearray);
    //System.out.println(byteBuffer.asIntBuffer().get(1));
    //Hexadecimal values used are Big-Endian, because Java is Big-Endian
    for (int i = 0; i < bytearray.length; i++) {
        byte thebyte = byteBuffer.get(i);
        for (int j = 0; j <8 ; j++) {
            returnValue.set(i*8+j,isBitSet(thebyte,j));
        }
    }
    return returnValue;
}

private static Boolean isBitSet(byte b, int bit)
{
    return (b & (1 << bit)) != 0;
}

我将使用JUnit测试进行测试,如下所示:

我将使用JUnit测试进行测试,如下所示。

@org.junit.Test
public void byteToBits() throws Exception {
    byte[] input = new byte[]{(byte) 0b1011_1011};
    BitSet expectedOutput = new BitSet(8);
    expectedOutput = BitSet.valueOf(new byte[]{(byte)0b1011_1011});
    assertEquals(expectedOutput,converter.byteToBits(input));
    assertEquals(expectedOutput.toByteArray(),input);
}

@Test
public void testBytestoBitslength() throws Exception {
    byte[] input = new byte[]{(byte) 0xFFFF,(byte)0x7F70,(byte)0xF45A,(byte)0xA24B};
    BitSet output = converter.byteToBits(input);
    System.out.println("byte[] length: "+input.length+ "x8: "+input.length*8);
    System.out.println("BitSet length: "+output.length());
    System.out.println(input.toString());
    System.out.println(output.toByteArray().toString());
    assertTrue(output.length()==input.length*8);
}

这段代码未通过测试,但我不知道原因。
对于byteToBits函数:
java.lang.AssertionError: 
Expected :[B@6438a396
Actual   :[B@e2144e4

对于testBytestoBitslength函数:

byte[] length: 4x8: 32
BitSet length: 31
[B@4f2410ac
[B@722c41f4

尝试使用BitSet.valueOf(byte[])方法替换它。但仍然失败,不过更有趣了。
@Test
public void curiosity() throws Exception {
    byte[] byteArray = new byte[]{1, 2, 3};
    BitSet bitSet = BitSet.valueOf(byteArray);
    System.out.println("byte[]: "+byteArray);
    System.out.println(bitSet.toByteArray());
    assertEquals(ByteBuffer.wrap(byteArray),ByteBuffer.wrap(bitSet.toByteArray()));
    assertEquals(bitSet.length(),byteArray.length*8);
}

这将返回以下内容:
byte[]: [B@6438a396
BitSet: [B@e2144e4

java.lang.AssertionError: 
Expected :18
Actual   :24

当被ByteBuffer包装时,这两个对象返回相同的结果,但它们看起来完全不同,并且这两个对象的长度不同。


你尝试过将 assertEquals(expectedOutput.toByteArray(),input); 替换为 assertEquals(ByteBuffer.wrap(expectedOutput.toByteArray()), ByteBuffer.wrap(input)); 吗? - Paul Boddington
@PaulBoddington 将 byte[] 包装在 ByteBuffer 中修复了 byteToBits 方法的 AssertionError。为什么它会修复错误? - user1
因为byte[]没有覆盖equals方法。对于byte[]equals方法只是测试它们是否完全相同的实例。您想要测试它们是否具有相同的长度和相同的元素。唯一的方法是使用Arrays.equals或将它们包装在ByteBuffer中并检查ByteBuffer是否相等。 - Paul Boddington
尝试运行 System.out.println(new byte[]{1, 2, 3}.equals(new byte[]{1, 2, 3}));。实际上会输出 false - Paul Boddington
有没有办法解决长度错误,还是那是另一个问题? - user1
我不确定那个,恐怕不行。 - Paul Boddington
2个回答

12

将字节转换为BitSet,您应该尝试使用

final byte b = ...;
final BitSet set = BitSet.valueOf(new byte[] { b });

你可以参考将字节或整数转换为位集,这可能会对你有所帮助。


2
我编辑了问题来尝试这个,但似乎不起作用。 - user1

1

不能直接比较两个byte[]数组,因为byte[]不实现可比较性。解决方案是将它们包装在ByteBuffer中,正如@PaulBoddington所建议的那样。

assertEquals(ByteBuffer.wrap(expectedOutput.toByteArray()),ByteBuffer.wrap(input));

另一个长度问题是由于BitSet本身引起的。BitSet.length()返回从索引0到BitSet中最后一个设置位的长度,这将导致BitSet.length()byte[].length*8的长度不一致。唯一的解决方案是在需要BitSet.length()时使用BitSet.toByteArray().length*8

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接