Цепочка блоков шифра: реализация XOR в Java

Как вы реализуете XOR из CBC (Cipher Block Chaining) в Java? Я знаю, как это сделать, когда оба моих значения являются логическими, но что мне делать, если у меня есть числа вместо логических?

Например:

i1 = 15
i2 = 4

Как мне XOR i1 и i2?


person Community    schedule 04.05.2017    source источник
comment
Возможный дубликат Создание логического исключения или оператора в Java   -  person    schedule 04.05.2017
comment
да, но я не хочу использовать логические операции XOR. Я хочу числа XOR :D   -  person    schedule 04.05.2017
comment
Он работает с логическими и целочисленными типами.   -  person    schedule 04.05.2017
comment
Итак, что не так с использованием i1 ^ i2 ?   -  person FSm    schedule 05.05.2017


Ответы (2)


В Java встроен побитовый оператор XOR, см. Спецификация языка Java. XOR работает со всеми примитивными целочисленными типами (т.е. типами, которые непосредственно представляют числа для вас и меня): byte, short, int, long и char. Этот оператор XOR выполняет побитовое XOR битов в одинаковых позициях, а затем выводит результат. Существует также ^=, который сохранит результат в левой переменной.

Теперь это зависит от вашей реализации CBC, будете ли вы делать это с байтами или с 32-битными целыми числами (int). Обычно вы будете использовать байты, но если вы реализовали AES с использованием 32-битных конструкций, вы должны использовать целые числа. Целые числа были бы немного быстрее, но время, которое занимает XOR, в любом случае будет меркнуть по сравнению с операцией блочного шифра.

Таким образом, вы можете просто иметь цикл for (до размера блока в байтах) и XOR каждого байта последнего зашифрованного текста со следующим открытым текстом во время шифрования или последнего зашифрованного текста с результатом - после расшифровки - следующего зашифрованного текста во время расшифровки. .


Возможно, вам придется вернуться к байту при использовании операции XOR для двухбайтовых значений, поскольку Java автоматически преобразует операнды — и, следовательно, результат — в 32-битные целые числа (int):

byte x = 0b0011; // 0b indicates a binary literal
byte y = 0b0101; 
byte r = (byte) (x ^ y); // results in 0b0110 or the value 6 in decimals

Байты — это значения со знаком в Java, что означает, что вы можете получить отрицательные значения. Это нормально, вы можете просто игнорировать это, пока используете только побитовые операции. Это важно только во время математических операций, таких как сложение или умножение.

person Maarten Bodewes    schedule 04.05.2017
comment
Спасибо Ammar за то, что вам нужно снова вернуться к байтам или шортам. - person Maarten Bodewes; 05.05.2017

используя short целых чисел:

short s1 = ...
short s2 = ...
short result = (short) (s1 ^ s2);

Это наиболее эффективный способ XOR между двумя шортами. Это не приводит к накладным расходам на создание BigInteger, и приведение никогда не вызовет проблемы переполнения, поскольку и s1, и s2 являются короткими с самого начала.

person Ammar Akouri    schedule 04.05.2017
comment
Однако нет абсолютно никакой причины использовать шорты. - person Maarten Bodewes; 05.05.2017