0

So i'm working on a bittorrent project. I need to create a bitfield according to number of piece. So i use BitSet but the problem is, the method toByteArray doesn't return the byte array in the order of byte that i wanted.

Eg:

//number of piece=11 
bitSet.set(5,16);  //following bittorrent specification

bitSet.toByteArray() -> 0xe0ff (this is the byte that i get)

But what i want is 0xffe0

Thanks in advance.

Jim Garrison
  • 85,615
  • 20
  • 155
  • 190
Nami
  • 1
  • You could use the bit-manipulation operators, like we did in the old days. Or just manipulate the order of the bytes. – NomadMaker Nov 18 '20 at 17:59
  • `0xe0ff` is not a byte, it's two bytes in unknown order. `bitSet.toByteArray()` actually returns `[-32, -1]`, aka `[0xe0, 0xff]`. As **documented** in the javadoc of [`toByteArray()`](https://docs.oracle.com/javase/8/docs/api/java/util/BitSet.html#toByteArray--): *Returns a byte array containing a **little-endian** representation of all the bits in this bit set.* --- If you want big-endian order, just reverse the bytes of the returned array, see: [How to reverse the byte array in java?](https://stackoverflow.com/q/12893758/5221149). – Andreas Nov 18 '20 at 19:05

1 Answers1

1

This is due to big-endian vs little-endian mismatch. BitSet is strictly bit-wise little-endian. BitSet#toByteArray() handles reversing the bit-order, but outputs little-endian bytes. So you'll have to rearrange the bytes yourself to match the desired order. The desired order will depend on the size of the "word" in your output data structure.

If the output is a short, you swap bytes 2 at a time, but if it's a long you'll need to reverse each set of 4 output bytes. It's possible to do this with a ByteBuffer but it's probably more work, unless you're already using ByteBuffers.

Unfortunately, there isn't a BitSet.toShortArray(), which would do what you want.

You might find the Wikipedia article Endianness useful.

Jim Garrison
  • 85,615
  • 20
  • 155
  • 190