heap.tech
лаборатория велосипедов
×

Bitwise. Побитовые операторы. Применение

21 января 2016
В прошлой статье я рассказал о том, что такое системы счисления, побитовые операторы и какими они бывают. Статья получилась достаточно емкой, но не было главного – для чего, как и где это все можно использовать. Во второй части статьи я заполню этот пробел примерами использования. Даешь больше примеров! Примеры я постарался привести не академические, то есть, применимые в больших и не очень проектах.

Поехали!

Первый пример, самый простой и очевидный – распределение прав пользователей. Грубо говоря, есть несколько учетных групп пользователей с разными правами. Этими правами нужно как-то управлять. Например, какой-то пользователь может создавать и просматривать файлы, кто-то только смотреть, а кто-то может делать любые операции (RWD).
Удобнее всего создать перечисление (ENUM) с заданными значениями, которые лучше задать кратно двойке, кроме этого их лучше задавать по возрастающее, от меньшего к большему. Самая низкая привилегия – самое маленькое значение. В нашем случае это привилегия Read, значение 1.

enum Rights { Read = 1, //0b00001 Edit = 2, //0b00010 Create = 4, //0b00100 Delete = 8 //0b01000 }

Любое число кратное двум (включая единицу) в степени два добавляет старший бит, равный 1. Это видно на примере.
Теперь можно задавать права пользователям, например, используя групповую политику

int adminRights = Rights.Create | Rights.Delete | Rights.Edit | Rights.Read; //15 или 0b01111 int guestRights = Rights.Read; //1 int userRights = Rights.Create | Rights.Edit | Rights.Read;//5 или 0b00101

Проверять права можно с помощью оператора &
(guestRights & Rights.Create) > 0//false или гость не может ничего создавать (userRights & Rights.Create) > 0//true, пользователи могут создавать


Второй пример. Преобразование чего-то длинного в байт-массив (byte[]). Такая необходимость возникает, если нужно передать какие-то данные по сети, например матрицу с большими числами. Хорошей практикой передачи таких данных является преобразование в байт-массив и последующая отправка, шаг за шагом. Для наглядности я упрощу задачу, ограничусь преобразованием целого числа int32 в массив.
Да, int32 – 32 бита минус один, который определяет знак числа. byte – 8 бит, без указания знака.
Пусть переменная будет равна 2147483647.

int i_32 = 0b0111 1111 1111 1111 1111 1111 1111 1111; //2147483647

Теперь представим значение переменной i_32 в виде массива байт

byte[] i32_array = new byte[4] { (byte)(i32 >> 24), (byte)(i32 >> 16), (byte)(i32 >> 8), (byte)i32 };

Готово. Серьезно. Супер серьезно!
Преобразование (byte)INT32_VALUE работает так – берутся младшие 8 бит из int. При каждом смещении мы получаем крайние 8 бит и преобразуем их в байт. Стильно, модно, молодежно. Для наглядности картинка


Третий пример. Шифрование. Для шифрования можно использовать побитовый оператор XOR или ^, это возможно, так как результат XOR обратим. Если, конечно, знать одно из чисел.
В примере я буду шифровать текстовую строчку в UTF-8 с определенным ключом, значение которого равно 255 или 0xFF или 0b11111111.
Да, пример на c#.

const byte XOR_KEY = 0xFF; const string MESSAGE_BODY = "Hi! How are you? This text going to crypted!"; static void Main(string[] args) { var str_bin = System.Text.Encoding.UTF8.GetBytes(Program.MESSAGE_BODY); var crypted_str_bin = new byte[str_bin.Length]; for (var c = 0; c < str_bin.Length; c++) crypted_str_bin[c] = (byte)(str_bin[c] ^ Program.XOR_KEY); Console.WriteLine(string.Format("crypted message:\n{0}\n\n", System.Text.Encoding.UTF8.GetString(crypted_str_bin))); for (var c = 0; c < str_bin.Length; c++) crypted_str_bin[c] = (byte)(crypted_str_bin[c] ^ XOR_KEY); Console.WriteLine(string.Format("decrypted message:\n{0}", System.Text.Encoding.UTF8.GetString(crypted_str_bin))); }

Готово. На строке 17 в консоль будет выведена зашифрованная строка. Чтобы показать, что процесс обратим и строчку можно расшифровать - еще раз XOR. В итоге на 23 строке получается исходная строка без изменений.
Но! Для реализации действительно стойких алгоритмов шифрования стоит использовать НЕ только XOR.
 
1611
0

Оставлять комментарии могут только зарегистрированные пользователи

пока никто не оставлял комментариев