У Crystal є побітові оператори для роботи з Int на рівні бітів.
У Crystal є оператори зсуву для зсуву бітів ліворуч (<<) або праворуч (>>).
<<)Оператор зсуву ліворуч (<<) зсуває біти ліворуч.
Значення для зсуву вказується ліворуч, а кількість позицій для зсуву - праворуч.
0b0010 << 1
# => 0b0100
0b0010 << 2
# => 0b1000
Якщо число відʼємне, зсув відбудеться праворуч.
0b0010 << -1
# => 0b0001
>>)Оператор зсуву праворуч (>>) зсуває біти праворуч.
Як і оператор зсуву ліворуч, він бере значення для зсуву ліворуч, а кількість позицій для зсуву - праворуч.
0b0100 >> 1
# => 0b0010
0b0100 >> 2
# => 0b0001
І так само, якщо число відʼємне, оператор зсуне біти ліворуч.
0b0100 >> -1
# => 0b1000
У Crystal є 3 бінарні оператори (&, |, ^) і оператор ~ для виконання побітових операцій.
&)Бінарний оператор AND (&) виконує побітове AND над двома значеннями.
Він порівнює кожен біт першого значення з бітом у тій самій позиції другого значення.
Результуючий біт встановлюється в 1, якщо обидва біти дорівнюють 1.
Інакше він встановлюється в 0.
0b0011 & 0b1010
# => 0b0010
|)Бінарний оператор OR (|) виконує побітове OR над двома значеннями.
Він так само порівнює кожен біт першого значення з бітом у тій самій позиції другого значення.
Якщо принаймні один із бітів дорівнює 1, результуючий біт встановлюється в 1.
Інакше він встановлюється в 0.
0b0011 | 0b1010
# => 0b1011
^)Бінарний оператор XOR (^) виконує побітове XOR.
Як і побітові оператори AND та OR, він порівнює кожен біт першого значення з бітом у тій самій позиції другого значення.
Якщо лише один із них дорівнює 1, результуючий біт дорівнює 1.
Інакше він дорівнює 0.
0b0011 ^ 0b1010
# => 0b1001
~)І нарешті, побітовий оператор NOT (~) інвертує кожен біт значення.
На відміну від інших бінарних операторів, це унарний оператор, який працює лише зі значенням праворуч.
~0b1110_0010
# => 0b0001_1101
Наш друг щойно надіслав нам повідомлення з важливим секретом. Не бажаючи, щоб інші легко його прочитали, він зашифрував повідомлення за допомогою низки маніпуляцій з бітами. Нам потрібно буде написати програму, яка допоможе розшифрувати повідомлення.
Щоб розшифрувати повідомлення, спочатку треба скасувати зсув, зроблений під час шифрування, зсунувши біти назад уліво. Кількість позицій для зсуву може відрізнятися залежно від повідомлення.
Реалізуйте метод Secrets.shift_back, який приймає значення та кількість позицій для зсуву вліво.
Secrets.shift_back(0b0001, 2)
# => 0b0100
Далі застосовуємо бітову маску, щоб видобути значення певних бітів. Маску застосовують, виконуючи побітове AND між значенням і маскою.
Реалізуйте метод Secrets.apply_mask, який приймає значення та застосовує до нього маску.
Secrets.apply_mask(0b0110, 0b0101)
# => 0b0100
Зсув бітів уліво додав нові біти зі значенням 0. Деякі з цих нових бітів потрібно встановити в 1. Побітове OR стає в пригоді, коли треба встановити певні біти в 1, зберігши решту без змін.
Реалізуйте метод Secrets.set_bits, який приймає два значення та виконує побітове OR.
Secrets.set_bits(0b0110, 0b0101)
# => 0b111
Частина процесу шифрування застосовує XOR з узгодженим значенням. Щоб повернутися до початкового значення, достатньо ще раз застосувати XOR до зашифрованого значення та узгодженого значення. Однак через непорозуміння наш друг перед застосуванням XOR перевернув біти узгодженого значення (тобто застосував побітове NOT до узгодженого значення).
Реалізуйте метод Secrets.reverse_xor, який приймає зашифроване значення й узгоджене значення та обчислює початкове значення.
Secrets.reverse_xor(0b1100, 0b0101)
# => 0b(0110)
Зареєструйтеся на Exercism, щоб вивчати й опановувати Crystal, а також 26 концепцій142 вправи та справжнє наставництво від людей, і все це безкоштовно.