Как я могу инвертировать биты неподписанного байта в Java?

Я пытаюсь записать декодер для очень простого типа шифрования. Номера от 0-255 введены через Сканер, биты инвертируются, и затем преобразовываются в символ и печатаются.

Например, номер 178 должен преобразовать в букву "M".

178 10110010.

Инвертирование всех битов должно дать 01001101, который равняется 77 или "M" как символ.

Основная проблема, которую я имею, состоит в том, что, насколько я могу сказать, Java не поддерживает неподписанные байты. Я мог считать значения как интервал или короткое, но затем значения будут выключены во время преобразования из-за дополнительных битов. Идеально я мог просто использовать оператор побитового дополнения, но я думаю, что закончу тем, что получил отрицательные величины, если я сделаю это с числами со знаком. Какие-либо идеи о том, как я должен приблизиться к этому?

16
задан DavidKelly999 24 July 2010 в 10:25
поделиться

5 ответов

Я бы просто использовал дополнение до единиц и избавился от других битов, используя бинарные и.

public class Conv {
    public static void main(String[] args) {
        int val = 178;
        val = ~val & 0xff;
        System.out.println((char) val);
    }
}
14
ответ дан 30 November 2019 в 17:26
поделиться

Побитовые операции в Java определены для int, поэтому имеет смысл работать с int, а не с byte. Вы можете использовать Scanner.nextInt, а не Scanner.nextByte. Вы должны проверить вводимые пользователем данные, чтобы убедиться, что все введенные целые числа находятся в диапазоне от 0 до 255, и вывести соответствующее сообщение об ошибке, если встречается число, выходящее за пределы диапазона.

После того, как вы сохранили число в виде целого числа, чтобы перевернуть младшие 8 бит, вы можете выполнить XOR с 0xff. Это должно сработать, как вы ожидаете, для всех входов от 0 до 255:

x ^= 0xff;

Пример:

String input = "178 0 255";
Scanner s = new Scanner(input);
while (s.hasNextInt()) {
    int x = s.nextInt();
    if (x < 0 || x > 255) {
        System.err.println("Not in range 0-255: " + x);
    } else {
        x ^= 0xff;
        System.out.println(x);
    }
}

Результат:

77
255
0
6
ответ дан 30 November 2019 в 17:26
поделиться
~n & 0xff

~ выполняет дополнение и неявно преобразует в целое число, как и все числовые операции, затем & 0xff маскирует все, кроме младших 8 бит, чтобы получить беззнаковое значение, снова как целое число.

Сначала я прочитал ваш вопрос иначе, чтобы изменить порядок вместо значений битов, и это был ответ.

Вы можете использовать Integer.reverse () (непроверено):

Integer.reverse(n << 24) & 0xff
11
ответ дан 30 November 2019 в 17:26
поделиться

Проще всего это сделать в три этапа:

  1. Считайте значение как int (32 бита в java). Оно может читаться как отрицательное, но в любом случае нас волнуют только 8 нижних бит. int i = scanner.nextByte();
  2. Выполните инверсию как int, используя побитовые операторы (как вы говорите, это даст вам 1s как биты старшего порядка: i = ~i;
  3. Потеряйте биты старшего порядка с помощью логического AND: i = i & 0xFF;

Затем просто используем результат как символ (который на самом деле 16 бит в java, но мы будем использовать только 8 из них):

char c=(char)a;
System.out.println(c); 

All together:

int i = scanner.nextByte(); // change this to nextInt() depending on file format
i = ~i;
i = i & 0xFF;
char c=(char)a;
System.out.println(c); 
0
ответ дан 30 November 2019 в 17:26
поделиться

Если Java поддерживает это, вы могли бы прочитать его в более крупный тип, побитово скомпоновать, а затем побитовой маской удалить ненужные биты.

int x = [your byte];
x = ~x & 0xFF;
2
ответ дан 30 November 2019 в 17:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: