Java boolean[] to byte[] and back
Solution 1
You could do it something like this.
public byte[] toBytes(boolean[] input) {
byte[] toReturn = new byte[input.length / 8];
for (int entry = 0; entry < toReturn.length; entry++) {
for (int bit = 0; bit < 8; bit++) {
if (input[entry * 8 + bit]) {
toReturn[entry] |= (128 >> bit);
}
}
}
return toReturn;
}
This relies on the fact that toReturn
will be initialised with all zeroes. Then for each true
that we encounter in input
, we set the appropriate bit within the appropriate entry in toReturn
.
Solution 2
There already exists a class (BitSet) in the standard library to help you do this, you should use that instead of a boolean array. The class allows you to get and set bits and to various logical operations on your boolean values as a group.
eg.
BitSet bits = BitSet.valueOf(bytes);
boolean third_bit = bits.get(3);
bits.set(5, false);
byte[] new_bytes = bits.toByteArray();
If you really need to use a boolean array then the following will work.
static boolean[] toBooleanArray(byte[] bytes) {
BitSet bits = BitSet.valueOf(bytes);
boolean[] bools = new boolean[bytes.length * 8];
for (int i = bits.nextSetBit(0); i != -1; i = bits.nextSetBit(i+1)) {
bools[i] = true;
}
return bools;
}
static byte[] toByteArray(boolean[] bools) {
BitSet bits = new BitSet(bools.length);
for (int i = 0; i < bools.length; i++) {
if (bools[i]) {
bits.set(i);
}
}
byte[] bytes = bits.toByteArray();
if (bytes.length * 8 >= bools.length) {
return bytes;
} else {
return Arrays.copyOf(bytes, bools.length / 8 + (bools.length % 8 == 0 ? 0 : 1));
}
}
Solution 3
For converting bytes to booleans:
public static boolean [] bytesToBooleans(byte [] bytes){
boolean [] bools = new boolean[bytes.length * 8];
byte [] pos = new byte[]{(byte)0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1};
for(int i = 0; i < bytes.length; i++){
for(int j = i * 8, k = 0; k < 8; j++, k++){
bools[j] = (bytes[i] & pos[k]) != 0;
}
}
return bools;
}
Or another method:
public static boolean [] bytesToBooleansAnotherWay(byte [] bytes){
boolean [] bools = new boolean[bytes.length * 8];
for(int i = 0; i < bytes.length; i++){
int j = i * 8;
bools[j] = (bytes[i] & 0x80) != 0;
bools[j + 1] = (bytes[i] & 0x40) != 0;
bools[j + 2] = (bytes[i] & 0x20) != 0;
bools[j + 3] = (bytes[i] & 0x10) != 0;
bools[j + 4] = (bytes[i] & 0x8) != 0;
bools[j + 5] = (bytes[i] & 0x4) != 0;
bools[j + 6] = (bytes[i] & 0x2) != 0;
bools[j + 7] = (bytes[i] & 0x1) != 0;
}
return bools;
}
Admin
Updated on June 04, 2022Comments
-
Admin almost 2 years
I am sending
byte[]
arrays over a socket connection in Java.I have a pretty long
boolean[]
array, wherearray.length % 8 == 0
.I'd like to convert this
boolean[]
array into abyte[]
array with 8 times as few elements, so that I can then send thebyte[]
over the socket connection.The
boolean[]
array looks like this:01011010 10101010 01100011 11001010
etc.The
byte[]
in this case should look like this:0x5A 0xAA 0x63 0xCA
.I have found some code on another question on how to convert a single
byte
into aboolean[]
array and added a new method to it to convert an entire array here:public static boolean[] booleanArrayFromByteArray(byte[] x) { boolean[] y = new boolean[x.length * 8]; int position = 0; for(byte z : x) { boolean[] temp = booleanArrayFromByte(z); System.arraycopy(temp, 0, y, position, 8); position += 8; } return y; } public static boolean[] booleanArrayFromByte(byte x) { boolean bs[] = new boolean[4]; bs[0] = ((x & 0x01) != 0); bs[1] = ((x & 0x02) != 0); bs[2] = ((x & 0x04) != 0); bs[3] = ((x & 0x08) != 0); return bs; }
I'd like to know if there is a more efficient way of doing this.
Edit: Thanks
-
Craigo about 8 yearsThis will ignore all false booleans. Ie: An array of booleans that are all false, will get an empty byte array.
-
Dunes about 8 yearsHmm, yes, this will ignore all higher zero bits after the last one bit. Not much effort to create a full sized empty byte array and copy over the bits byte array though.
-
pfurbacher about 7 yearsWith Java 8, in the "toBooleanArray(...)" method, you could replace the "for" loop with "bits.stream().forEach(bit -> bools[bit] = true);". It's a bit more succinct for the same work. (Not a really big deal, though.)