VB.NET не поддерживает операции на битовом уровне напрямую. Framework 1.1 (VB.NET 2003) представил операторы сдвига битов (<< и >>), но нет универсального способа манипулирования отдельными битами. Битовые операции мочь быть очень полезным. Например, ваша программа может взаимодействовать с другой системой, которая требует битовых манипуляций. Но кроме того, есть много хитростей, которые можно сделать, используя отдельные биты. В этой статье рассматривается, что можно сделать с помощью битовых манипуляций с использованием VB.NET.
Вам нужно понять побитовые операторы прежде всего В VB.NET это:
- И
- Или
- Xor
- Не
Побитовый просто означает, что операции могут выполняться над двумя двоичными числами побитно. Microsoft использует таблицы правды документировать побитовые операции. Таблица правды для И является:
1-й бит 2-битный результат
1 1 1
1 0 0
0 1 0
0 0 0
В моей школе они учили Карно карты вместо. Карта Карно для всех четырех операций показана на рисунке ниже.
Нажмите здесь, чтобы отобразить иллюстрацию
Нажмите кнопку «Назад» в вашем браузере, чтобы вернуться
Вот простой пример использования И работа с двух-, четырехбитными двоичными числами:
Результат 1100 И 1010 это 1000.
Это потому что 1 И 1 - 1 (первый бит), а остальные - 0.
Для начала давайте посмотрим на битовые операции, которые находятся напрямую поддерживается в VB.NET: сдвиг немного. Хотя доступны как левый, так и правый сдвиг, они работают одинаково, поэтому будет обсуждаться только левый сдвиг. Сдвиг битов чаще всего используется в криптографии, обработке изображений и связи.
Операции сдвига битов в VB.NET ...
- Работайте только с четырьмя типами целых чисел: Байт, короткий, целое число, и Длинная
- Находятся арифметика сменные операции. Это означает, что биты, сдвинутые после конца результата, выбрасываются, а позиции битов, открытые на другом конце, устанавливаются в ноль. Альтернатива называется циклическим битовым сдвигом, и биты, сдвинутые за один конец, просто добавляются к другому. VB.NET не поддерживает прямое круговое смещение. Если вам это нужно, вам придется кодировать его старомодным способом: умножение или деление на 2.
- Никогда не создавайте исключение переполнения. VB.NET позаботится о любых возможных проблемах, и я покажу вам, что это значит. Как уже отмечалось, вы можете закодировать свой собственный сдвиг битов, умножив или разделив на 2, но если вы используете «кодируй свой» подход, вы должны проверить исключения переполнения, которые могут вызвать вашу программу врезаться.
Стандартная операция сдвига битов будет выглядеть примерно так:
Dim StartingValue As Integer = 14913080
Dim ValueAfterShifting As Integer
ValueAfterShifting = StartingValue << 50
На словах эта операция принимает двоичное значение 0000 0000 1110 0011 1000 1110 0011 1000 (14913080 - это эквивалентное десятичное значение - обратите внимание, что это просто серия из 3 0 и 3 1, повторенная несколько раз) и сдвигает его на 50 позиций влево. Но поскольку Integer имеет длину всего 32 бита, сдвигать его на 50 позиций бессмысленно. VB.NET решает эту проблему путем маскировка число сдвигов со стандартным значением, которое соответствует используемому типу данных. В таком случае, ValueAfterShifting является целое число таким образом, максимум, который может быть сдвинут, составляет 32 бита. Стандартное значение маски, которое работает, является 31 десятичным или 11111.
маскировка означает, что значение, в данном случае 50, является ИЭд с маской. Это дает максимальное количество битов, которые фактически могут быть сдвинуты для этого типа данных.
В десятичном виде:
50 А 31 является 18 - Максимальное количество битов, которые можно сдвинуть
Это на самом деле имеет больше смысла в двоичном. Биты старшего разряда, которые нельзя использовать для операции сдвига, просто удаляются.
110010 А 11111 является 10010
Когда выполняется фрагмент кода, результатом является 954204160 или, в двоичном, 0011 1000 1110 0000 0000 0000 0000 0000. 18 бит на левой стороне первого двоичного числа смещены, а 14 бит на правой стороне смещены влево.
Другая большая проблема со сдвигом битов заключается в том, что происходит, когда количество мест для сдвига является отрицательным числом. Давайте используем -50 в качестве количества бит для сдвига и посмотрим, что произойдет.
ValueAfterShifting = StartingValue << -50
Когда этот фрагмент кода выполняется, мы получаем -477233152 или 1110 0011 1000 1110 0000 0000 0000 0000 в двоичном виде. Номер был сдвинут на 14 мест влево. Почему 14? VB.NET предполагает, что число мест является целым числом без знака и выполняет И работа с той же маской (31 для целых чисел).
1111 1111 1111 1111 1111 1111 1100 1110
0000 0000 0000 0000 0000 0000 0001 1111
(И)
0000 0000 0000 0000 0000 0000 0000 1110
1110 в двоичном формате - 14 десятичных. Обратите внимание, что это обратное смещение положительных 50 мест.
На следующей странице мы переходим к некоторым другим битовым операциям, начиная с Xor Encryption!
Я упомянул, что одним из применений битовых операций является шифрование. Xor шифрование - это популярный и простой способ «зашифровать» файл. В моей статье «Очень простое шифрование с использованием VB.NET» я покажу вам лучший способ использования строковых манипуляций. Но шифрование Xor настолько распространено, что заслуживает, по крайней мере, объяснения.
Шифрование текстовой строки означает перевод ее в другую текстовую строку, которая не имеет очевидной связи с первой. Вы также нуждаетесь в способе расшифровать это снова. Шифрование Xor переводит двоичный код ASCII для каждого символа в строке в другой символ с помощью операции Xor. Чтобы сделать этот перевод, вам нужен другой номер для использования в Xor. Этот второй номер называется ключом.
Xor-шифрование называется «симметричным алгоритмом». Это означает, что мы также можем использовать ключ шифрования в качестве ключа дешифрования.
Давайте используем «A» в качестве ключа и зашифруем слово «Basic». Код ASCII для «A»:
0100 0001 (десятичное 65)
Код ASCII для Basic:
B - 0100 0010
а - 0110 0001
с - 0111 0011
я - 0110 1001
с - 0110 0011
Xor каждого из них:
0000 0011 - десятичное 3
0010 0000 - десятичное 32
0011 0010 - десятичный 50
0010 1000 - десятичный 40
0010 0010 - десятичный 34
Эта маленькая рутина делает свое дело:
- Xor Encryption -
Дим я как короткий
ResultString. Текст = ""
Dim KeyChar As Integer
KeyChar = Asc (EncryptionKey. Текст)
Для я = 1 до Лен (InputString. Текст)
ResultString. Текст & = _
Chr (KeyChar Xor _
Asc (Mid (InputString. Текст, я, 1)))
следующий
Результат можно увидеть на этой иллюстрации:
Нажмите здесь, чтобы отобразить иллюстрацию
Нажмите кнопку «Назад» в вашем браузере, чтобы вернуться
Чтобы отменить шифрование, просто скопируйте и вставьте строку из текстового поля Result обратно в текстовое поле String и снова нажмите кнопку.
Другим примером того, что вы можете сделать с побитовыми операторами, является замена двух целых чисел без объявления третьей переменной для временного хранения. Это то, что они делали в программах на ассемблере много лет назад. Сейчас это не слишком полезно, но вы можете однажды выиграть пари, если найдете кого-то, кто не верит, что вы можете это сделать. В любом случае, если у вас остались вопросы о том, как Xor работает, проработка этого должна положить их в покое. Вот код:
Dim FirstInt As Integer
Dim SecondInt As Integer
FirstInt = CInt (FirstIntBox. Текст)
SecondInt = CInt (SecondIntBox. Текст)
FirstInt = FirstInt Xor SecondInt
SecondInt = FirstInt Xor SecondInt
FirstInt = FirstInt Xor SecondInt
ResultBox. Text = "First Integer:" & _
FirstInt. Нанизывать & " - " & _
"Второе целое число:" & _
SecondInt. Нанизывать
А вот код в действии:
Нажмите здесь, чтобы отобразить иллюстрацию
Нажмите кнопку «Назад» в вашем браузере, чтобы вернуться
Выяснение, почему именно эти работы будут оставлены как «в качестве упражнения для студента».
На следующей странице мы достигаем цели: Общее управление битами
Хотя эти трюки веселые и познавательные, они по-прежнему не могут заменить обычные манипуляции с битами. Если вы действительно опуститесь до уровня битов, вам нужен способ проверить отдельные биты, установить их или изменить их. Это реальный код, который отсутствует в .NET.
Возможно, причина этого в том, что не так сложно написать подпрограммы, которые выполняют то же самое.
Типичная причина, по которой вы можете захотеть сделать это, состоит в том, чтобы поддерживать то, что иногда называют флаг байта. Некоторые приложения, особенно написанные на языках низкого уровня, таких как ассемблер, будут поддерживать восемь логических флагов в одном байте. Например, регистр состояния чипа процессора 6502 хранит эту информацию в одном 8-битном байте:
Бит 7 Отрицательный флаг
Бит 6 Флаг переполнения
Бит 5 неиспользуемый
Бит 4 Разбить флаг
Бит 3 Десятичный флаг
Бит 2 Флаг отключения прерывания
Бит 1 Нулевой флаг
Бит 0 Нести флаг
(из Википедии)
Если ваш код должен работать с данными такого типа, вам необходим универсальный код для манипуляции с битами. Этот код сделает работу!
'ClearBit Sub очищает 1-й, n-й бит
'(MyBit) целого числа (MyByte).
Sub ClearBit (ByRef MyByte, ByVal MyBit)
Dim BitMask As Int16
'Создайте битовую маску с установленным битом мощности от 2 до n:
BitMask = 2 ^ (MyBit - 1)
«Очистить n-й бит:
MyByte = MyByte, а не BitMask
End Sub
'Функция ExamineBit вернет True или False
'в зависимости от значения 1-го, n-го бита (MyBit)
целого числа (MyByte).
Функция ExamineBit (ByVal MyByte, ByVal MyBit) как логическое значение
Dim BitMask As Int16
BitMask = 2 ^ (MyBit - 1)
ExamineBit = ((MyByte и BitMask)> 0)
Конечная функция
'SubBit Sub установит 1-й, n-й бит
'(MyBit) целого числа (MyByte).
Sub SetBit (ByRef MyByte, ByVal MyBit)
Dim BitMask As Int16
BitMask = 2 ^ (MyBit - 1)
MyByte = MyByte или BitMask
End Sub
'ToggleBit Sub изменит состояние
'из 1-го, n-го бита (MyBit)
целого числа (MyByte).
Sub ToggleBit (ByRef MyByte, ByVal MyBit)
Dim BitMask As Int16
BitMask = 2 ^ (MyBit - 1)
MyByte = MyByte Xor BitMask
End Sub
Чтобы продемонстрировать код, эта процедура вызывает его (параметры, не закодированные в Click Sub):
Частный Sub ExBitCode_Click (...
Dim Byte1, Byte2 As Byte
Dim MyByte, MyBit
Dim StatusOfBit As Boolean
Dim SelectedRB As String
Строки статуса. Текст = ""
SelectedRB = GetCheckedRadioButton (Me). Имя
Byte1 = ByteNum. Текстовый номер для преобразования в битовые флаги
Byte2 = BitNum. Текст 'бит для переключения
«Следующий очищает старший байт и возвращает только
младший байт:
MyByte = Byte1 И & HFF
MyBit = Byte2
Выбрать дело SelectedRB
Кейс "ClearBitButton"
ClearBit (MyByte, MyBit)
Строки статуса. Text = "New Byte:" & MyByte
Дело "ExamineBitButton"
StatusOfBit = ExamineBit (MyByte, MyBit)
Строки статуса. Text = "Bit" & MyBit & _
"is" & StatusOfBit
Кейс "SetBitButton"
SetBit (MyByte, MyBit)
Строки статуса. Text = "New Byte:" & MyByte
Кейс "ToggleBitButton"
ToggleBit (MyByte, MyBit)
Строки статуса. Text = "New Byte:" & MyByte
Конец выбора
End Sub
Частная функция GetCheckedRadioButton (_
ByVal Parent As Control) _
Как RadioButton
Dim FormControl As Control
Dim RB As RadioButton
Для каждого FormControl In Parent. управления
Если FormControl. GetType () Is GetType (RadioButton) Тогда
RB = DirectCast (FormControl, RadioButton)
Если RB.Checked, то вернуть RB
End If
следующий
Ничего не вернуть
Конечная функция
Код в действии выглядит так:
Нажмите здесь, чтобы отобразить иллюстрацию
Нажмите кнопку «Назад» в вашем браузере, чтобы вернуться