4

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.

user1
  • 57
  • 1
  • 8
  • Have you tried replacing `assertEquals(expectedOutput.toByteArray(),input);` with `assertEquals(ByteBuffer.wrap(expectedOutput.toByteArray()), ByteBuffer.wrap(input));`? – Paul Boddington Mar 22 '16 at 03:53
  • @PaulBoddington Wrapping the byte[]s in a ByteBuffer fixed the AssertionError for the byteToBits method. Why did it fix the error? – user1 Mar 22 '16 at 03:57
  • Because `byte[]` does not override `equals`. `equals` for `byte[]` simply tests if they are exactly the same instance. You want to test if they have the same length and the same elements. The only ways to do this is `Arrays.equals` or to wrap them in `ByteBuffer`s and check the ByteBuffers are equal. – Paul Boddington Mar 22 '16 at 03:59
  • Try `System.out.println(new byte[]{1, 2, 3}.equals(new byte[]{1, 2, 3}));`. It actually prints `false`. – Paul Boddington Mar 22 '16 at 04:01
  • Is there any way to fix the length error, or is that a different problem? – user1 Mar 22 '16 at 04:04
  • I'm not sure about that one, I'm afraid. – Paul Boddington Mar 22 '16 at 04:09

2 Answers2

11

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.

Community
  • 1
  • 1
mnpoonia
  • 2,056
  • 1
  • 14
  • 8
0

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

user1
  • 57
  • 1
  • 8