Я пытаюсь записать декодер для очень простого типа шифрования. Номера от 0-255 введены через Сканер, биты инвертируются, и затем преобразовываются в символ и печатаются.
Например, номер 178 должен преобразовать в букву "M".
178 10110010.
Инвертирование всех битов должно дать 01001101, который равняется 77 или "M" как символ.
Основная проблема, которую я имею, состоит в том, что, насколько я могу сказать, Java не поддерживает неподписанные байты. Я мог считать значения как интервал или короткое, но затем значения будут выключены во время преобразования из-за дополнительных битов. Идеально я мог просто использовать оператор побитового дополнения, но я думаю, что закончу тем, что получил отрицательные величины, если я сделаю это с числами со знаком. Какие-либо идеи о том, как я должен приблизиться к этому?
Я бы просто использовал дополнение до единиц и избавился от других битов, используя бинарные и.
public class Conv {
public static void main(String[] args) {
int val = 178;
val = ~val & 0xff;
System.out.println((char) val);
}
}
Побитовые операции в 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
~n & 0xff
~
выполняет дополнение и неявно преобразует в целое число, как и все числовые операции, затем & 0xff
маскирует все, кроме младших 8 бит, чтобы получить беззнаковое значение, снова как целое число.
Сначала я прочитал ваш вопрос иначе, чтобы изменить порядок вместо значений битов, и это был ответ.
Вы можете использовать Integer.reverse ()
(непроверено):
Integer.reverse(n << 24) & 0xff
Проще всего это сделать в три этапа:
int i = scanner.nextByte();
i = ~i;
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);
Если Java поддерживает это, вы могли бы прочитать его в более крупный тип, побитово скомпоновать, а затем побитовой маской удалить ненужные биты.
int x = [your byte];
x = ~x & 0xFF;