Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 524
user1 Avatar asked Oct 18 '25 10:10

user1


2 Answers

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.

like image 127
mnpoonia Avatar answered Oct 20 '25 00:10

mnpoonia


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().

like image 29
user1 Avatar answered Oct 19 '25 22:10

user1



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!