Операнды преобразуются в 32-битные целые числа, представленные последовательностью битов. Дробная часть, если она есть, отбрасывается.
Для бинарных операторов — каждый бит в первом операнде рассматривается вместе с соответствующим битом второго операнда: первый бит с первым, второй со вторым и т.п. Оператор применяется к каждой паре бит, давая соответствующий бит результата.
Получившаяся в результате последовательность бит интерпретируется как обычное число.
Посмотрим, как работают операторы, на примерах.
& (побитовое И)
Выполняет операцию И над каждой парой бит.
Результат a & b равен единице только когда оба бита a и b равны единице.
Таблица истинности для &:
a
b
a & b
Пример:
9 (по осн. 10)
= 00000000000000000000000000001001 (по осн. 2)
14 (по осн. 10)
= 00000000000000000000000000001110 (по осн. 2)
--------------------------------
14 & 9 (по осн. 10)
= 00000000000000000000000000001000 (по осн. 2)
= 8 (по осн. 10)
| (Побитовое ИЛИ)
Выполняет операцию ИЛИ над каждой парой бит. Результат a | b равен 1, если хотя бы один бит из a,b равен 1.
Таблица истинности для |:
a
b
a | b
Пример:
9 (по осн. 10)
= 00000000000000000000000000001001 (по осн. 2)
14 (по осн. 10)
= 00000000000000000000000000001110 (по осн. 2)
--------------------------------
14 | 9 (по осн. 10)
= 00000000000000000000000000001111 (по осн. 2)
= 15 (по осн. 10)
^ (Исключающее ИЛИ)
Выполняет операцию «Исключающее ИЛИ» над каждой парой бит.
a Исключающее ИЛИ b равно 1, если только a=1 или только b=1, но не оба одновременно a=b=1.
Таблица истинности для исключающего ИЛИ:
a
b
a ^ b
Как видно, оно даёт 1, если ЛИБО слева 1, ЛИБО справа 1, но не одновременно. Поэтому его и называют «исключающее ИЛИ».
Пример:
9 (по осн. 10)
= 00000000000000000000000000001001 (по осн. 2)
14 (по осн. 10)
= 00000000000000000000000000001110 (по осн. 2)
--------------------------------
14 ^ 9 (по осн. 10)
= 00000000000000000000000000000111 (по осн. 2)
= 7 (по осн. 10)
Исключающее ИЛИ в шифровании
Исключающее или можно использовать для шифрования, так как эта операция полностью обратима. Двойное применение исключающего ИЛИ с тем же аргументом даёт исходное число.
Иначе говоря, верна формула: a ^ b ^ b == a.
Пускай Вася хочет передать Пете секретную информацию data. Эта информация заранее превращена в число, например строка интерпретируется как последовательность кодов символов.
Вася и Петя заранее договариваются о числовом ключе шифрования key.
Алгоритм:
Вася берёт двоичное представление data и делает операцию data ^ key. При необходимости data бьётся на части, равные по длине key, чтобы можно было провести побитовое ИЛИ ^ по всей длине. JavaScript позволяет делать операцию ^ с 32-битными целыми числами, так что data нужно разбить на последовательность таких чисел.
Результат data ^ key отправляется Пете, это шифровка.
Например, пусть в data очередное число равно 9, а ключ key равен 1220461917.
Данные: 9 в двоичном виде
Ключ: 1220461917 в двоичном виде
Результат операции 9 ^ key:
Результат в 10-ной системе (шифровка):
Петя, получив очередное число шифровки 1220461908, применяет к нему такую же операцию ^ key.
Результатом будет исходное число data.
В нашем случае:
Полученная шифровка в двоичной системе:
9 ^ key = 1220461908
Ключ: 1220461917 в двоичном виде:
Результат операции 1220461917 ^ key:
Результат в 10-ной системе (исходное сообщение):
Конечно, такое шифрование поддаётся частотному анализу и другим методам дешифровки, поэтому современные алгоритмы используют XOR как одну из важных частей более сложной многоступенчатой схемы.
~ (Побитовое НЕ)
Производит операцию НЕ над каждым битом, заменяя его на обратный ему.
Таблица истинности для НЕ:
a
~a
Пример:
9 (по осн. 10)
= 00000000000000000000000000001001 (по осн. 2)
--------------------------------
~9 (по осн. 10)
= 11111111111111111111111111110110 (по осн. 2)
= -10 (по осн. 10)
Из-за внутреннего представления отрицательных чисел получается так, что ~n == -(n+1).