Прочитать отдельные биты из массива байтов
Есть массив байт (byte[] data), нужно записать его в JSON и потом прочитать из JSON. Предполагал сделать это побитово, распознав в каждом байте 1 и 0 и записав их в строку, а между отдельными байтами вставив разделитель в виде маловероятной последовательности символов. Строки всех байтов последовательно конкатенировать и записать в JSON. Но возникает вопрос, как максимально просто прочитать отдельные биты из байта (без использования сторонних библиотек)?
Ответы (3 шт):
Задача решается довольно просто. Например, так:
byte[] data = {127,126,125};
for (byte datum : data) {
String bitsString = Integer.toBinaryString((int)datum);
System.out.println(bitsString); //Напечатайте, или сделайте с битами что-то ещё
}
Это (возможно) не окончательное решение, так как у битов не будет ведущих нулей. То есть, если вам нужно представить число 2 в виде строки так: "0010", то два первых нуля придётся добавить вручную, так как данный способ превратит число 2 в строку "10". Но из вопроса непонятно, нужно это или нет.
Общая логика решения такова. У класса Integer есть статический метод toBinaryString. Этот метод возвращает строку битов, переданного целого числа типа int. Поскольку у нас массив byte, а не int, нам нужно делать привидение типов, что и происходит. С полученной строкой делаем, что хотим.
Самый простой вариант, как видится мне во всяком случае, это использование комбинации простых побитовых операций. Конкретно, небольшой алгоритм a & (~a ^ (1 << (bitIndex - 1))), где a - байт в котором происходит проверка. Если полученный байт равен 0 - бит был нулевой, если отличное от 0 - бит был равен 1.
bitIndex - позиция бита, значения которого вы хотите проверить.
Пример:
исходный байт (a) - 1 1 0 0 1 1 0 0
инверсия данного байта (~a) - 0 0 1 1 0 0 1 1
(~a ^ (1 << 5 - 1)) - 0 0 1 1 1 0 1 1
a & (~a ^ (1 << 5 - 1)) - 0 0 0 0 1 0 0 0
Пример 2:
исходный байт (a) - 1 1 0 0 0 1 0 0
инверсия данного байта (~a) - 0 0 1 1 1 0 1 1
(~a ^ (1 << 5 - 1)) - 0 0 1 1 0 0 1 1
a & (~a ^ (1 << 5 - 1)) - 0 0 0 0 0 0 0 0
Если нужны ведущие нули
byte[] data = {127,126,125};
for (byte datum : data) {
String bitsString = Integer.toBinaryString(datum & 0xff | 0x100).substring(1);
System.out.println(bitsString); //Напечатайте, или сделайте с битами что-то ещё
}