繁体   English   中英

Java BitSet从/到字节数组的错误转换

[英]Java BitSet wrong conversion from/to byte array

使用BitSet,我的测试失败:

BitSet bitSet = new BitSet();
bitSet.set(1);
bitSet.set(100);
logger.info("BitSet: " + BitSetHelper.toString(bitSet));
BitSet fromByteArray = BitSetHelper.fromByteArray(bitSet.toByteArray());
logger.info("fromByteArray: " + BitSetHelper.toString(bitSet));
Assert.assertEquals(2, fromByteArray.cardinality());
Assert.assertTrue(fromByteArray.get(1));  <--Assertion fail!!! 
Assert.assertTrue(fromByteArray.get(100)); <--Assertion fail!!!

更奇怪的是,我可以看到两个BitSet的String表示形式:

17:34:39.194 [main] INFO  c.i.uniques.helper.BitSetHelperTest - BitSet: 00000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000
17:34:39.220 [main] INFO  c.i.uniques.helper.BitSetHelperTest - fromByteArray: 00000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000

等于! 这里发生了什么事??

此示例上使用的方法是:

public static BitSet fromByteArray(byte[] bytes) {
        BitSet bits = new BitSet();
        for (int i = 0; i < bytes.length * 8; i++) {
            if ((bytes[bytes.length - i / 8 - 1] & (1 << (i % 8))) > 0) {
                bits.set(i);
            }
        }
        return bits;
    }

以及用于获取String表示形式的方法:

public static String toString(BitSet bitSet) {
        StringBuffer buffer = new StringBuffer();
        for (byte b : bitSet.toByteArray()) {
            buffer.append(String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0'));
        }
        return buffer.toString();
    }

有人可以解释这里发生了什么吗?

请注意, BitSet有一个valueOf(byte[])已经为您完成此操作。

在您的fromByteArray方法内部

for (int i = 0; i < bytes.length * 8; i++) {
    if ((bytes[bytes.length - i / 8 - 1] & (1 << (i % 8))) > 0) {
        bits.set(i);
    }
}

您正在反向遍历byte[] 在第一次迭代中,

bytes.length - i / 8 - 1

将评估为

8 - (0 / 8) - 1

这是7 ,它将访问最高有效字节。 这是包含原始位集中的第100个位的位。 从背面看,这是第四位。 并且,如果您检查生成的BitSet设置的位,则会注意到第5位和第98位(这里可能是一个错误关闭)而已设置。

但是toByteArray()返回的byte[]包含

该位集中所有位的小端序表示

您需要以适当的顺序读取byte[]

for (int i = 0; i < bytes.length * 8; i++) {
    if ((bytes[i / 8] & (1 << (i % 8))) > 0) {
        bits.set(i);
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM