简体   繁体   中英

Convert byte[] to BitSet

I'm trying to convert a byte array to a BitSet. The following is the code I'm using:

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;
}

I'm testing it with a JUnit test, shown below.

@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);
}

This code fails the test though, and I have no idea why.

For byteToBits:

java.lang.AssertionError: 
Expected :[B@6438a396
Actual   :[B@e2144e4

For testBytestoBitslength:

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

Tried replacing it with a BitSet.valueOf(byte[]) method call. It still fails, albeit more interestingly.

@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);
}

This returns the following:

byte[]: [B@6438a396
BitSet: [B@e2144e4

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

When wrapped by a ByteBuffer, the two objects return the same thing, but they appear to be completely different, and the two objects have different lengths.

For converting byte to BitSet you should try

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

You can refer to Convert a byte or int to bitset it might help you.

One cannot compare two byte[] arrays directly, as byte[] s dont implement comparable. The solution here would be to wrap them in a ByteBuffer, as suggested by @PaulBoddington.

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

The other length issue is caused by BitSet itself. BitSet.length() returns the length from index 0 to the last set bit in the BitSet , which would cause the discrepancy in the length of the BitSet.length() vs the byte[].length*8 . The only solution here would be to use BitSet.toByteArray().length*8 , where ever there is a need for BitSet.length() .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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