VB.NET не поддържа директно операции на ниво бит. Рамка 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
В моето училище те преподаваха Karnaugh карти вместо това. Картата на Karnaugh за всички четири операции е показана на илюстрацията по-долу.
Щракнете тук, за да покажете илюстрацията
Щракнете върху бутона Назад в браузъра си, за да се върнете
Ето един прост пример с помощта на И работа с две, четири битни двоични числа:
Резултатът от 1100 И 1010 е 1000.
Това е така, защото 1 И 1 е 1 (първият бит), а останалите са 0.
Като начало, нека да разгледаме битовите операции, които сте директно поддържан във VB.NET: битово изместване. Въпреки че са налични както смяна на ляво, така и дясно, те работят по същия начин, така че ще се обсъжда само смяна вляво. Преместването на бита се използва най-често в криптографията, обработката на изображения и комуникациите.
Операциите на VB.NET за изместване на бит ...
- Работете само с четирите типа цели числа: байт, Къс, цяло число, и дълго
- сте аритметика операции по изместване. Това означава, че битовете, изместени в края на резултата, се изхвърлят, а битовите позиции, отворени в другия край, са зададени на нула. Алтернативата се нарича кръгово разместване на бита и битовете, изместени от единия край, просто се добавят към другия. VB.NET не поддържа директно кръгово преместване на бита. Ако имате нужда, ще трябва да го кодирате по старомодния начин: умножаване или деление на 2.
- Никога не генерирайте изключение за препълване. VB.NET се грижи за всички възможни проблеми и ще ви покажа какво означава това. Както бе отбелязано, можете да кодирате собственото си преместване на бита, като умножите или делите на 2, но ако използвате "кодирайте свой собствен" подход, трябва да тествате за изключения от препълване, които могат да доведат до вашата програма катастрофа.
Една стандартна операция за смяна на бита ще изглежда така:
Dim StartingValue като цяло число = 14913080
Dim ValueAfterShifting като цяло число
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 0000. 18 бита от лявата страна на първото двоично число са изместени и 14 бита от дясната страна са изместени наляво.
Другият голям проблем с преместването на битовете е това, което се случва, когато броят на местата за преместване е отрицателно число. Нека използваме -50 като брой битове, за да сменим и да видим какво ще се случи.
ValueAfterShifting = StartingValue << -50
Когато този фрагмент на код се изпълни, получаваме -477233152 или 1110 0011 1000 1110 0000 0000 0000 0000 в двоичен код. Броят е изместен 14 места, останали. Защо 14? VB.NET приема, че броят на местата е без подписано цяло число и прави an И работа със същата маска (31 за Integers).
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 Шифроване!
Споменах, че едно използване на битови операции е криптиране. Шифроването на Xor е популярен и прост начин за "криптиране" на файл. В моята статия, Много просто шифроване с помощта на VB.NET, аз ви показвам по-добър начин, използвайки стриктно манипулиране. Но криптирането на Xor е толкова често, че заслужава поне да бъде обяснено.
Шифроването на текстов низ означава превеждането му в друг текстов низ, който няма очевидна връзка с първия. Трябва ви също начин да го декриптирате отново. Xor криптиране превежда двоичния ASCII код за всеки символ в низа в друг символ, използвайки операцията Xor. За да направите този превод, имате нужда от друг номер, който да използвате в Xor. Това второ число се нарича ключ.
Криптирането на Xor се нарича "симетричен алгоритъм". Това означава, че можем да използваме ключа за криптиране и като ключ за декриптиране.
Нека използваме "A" като ключ и криптираме думата "Basic". ASCII кодът за „A“ е:
0100 0001 (десетична 65)
ASCII кодът за Basic е:
Б - 0100 0010
a - 0110 0001
s - 0111 0011
i - 0110 1001
в - 0110 0011
Най- XOR всяко от тях е:
0000 0011 - десетичен 3
0010 0000 - десетичен 32
0011 0010 - десетичен 50
0010 1000 - десетичен 40
0010 0010 - десетичен 34
Тази малка рутина прави трика:
- Xor Шифроване -
Dim i като къс
ResultString. Текст = ""
Dim KeyChar като цяло число
KeyChar = Asc (EncryptionKey. Текст)
За i = 1 до Лен (InputString Текст)
ResultString. Текст & = _
Chr (KeyChar Xor _
Asc (Mid (InputString) Текст, i, 1)))
Следващия
Резултатът може да се види на тази илюстрация:
Щракнете тук, за да покажете илюстрацията
Щракнете върху бутона Назад в браузъра си, за да се върнете
За да обърнете криптирането, просто копирайте и поставете низ от Result TextBox обратно в String TextBox и кликнете отново върху бутона.
Друг пример за нещо, което можете да направите с битови оператори, е да замените два цели числа, без да декларирате трета променлива за временно съхранение. Това е нещо, което преди са правили в програмите за монтаж на езици преди години. Сега не е твърде полезно, но може да спечелите залог някой ден, ако намерите някой, който не вярва, че можете да го направите. Във всеки случай, ако все още имате въпроси как XOR работи, работата чрез това трябва да ги остави да почиват. Ето кода:
Dim FirstInt като цяло число
Dim SecondInt като цяло число
FirstInt = CInt (FirstIntBox. Текст)
SecondInt = CInt (SecondIntBox. Текст)
FirstInt = FirstInt Xor SecondInt
SecondInt = FirstInt Xor SecondInt
FirstInt = FirstInt Xor SecondInt
ResultBox. Text = "Първо цяло число:" & _
FirstInt. ToString & "-" & _
"Втори цяло число:" & _
SecondInt. ToString
И ето кода в действие:
Щракнете тук, за да покажете илюстрацията
Щракнете върху бутона Назад в браузъра си, за да се върнете
Измислянето точно защо това работи ще бъде оставено като "като упражнение за ученика".
На следващата страница достигаме целта: Обща манипулация на битовете
Въпреки че тези трикове са забавни и образователни, те все още не заместват общата битова манипулация. Ако наистина се спуснете до нивото на битовете, това, което искате, е начин да изследвате отделните битове, да ги задавате или да ги променяте. Това е истинският код, който липсва на .NET.
Може би причината да липсва е, че не е толкова трудно да се напишат подпрограми, които постигат едно и също нещо.
Типична причина, поради която може да искате да направите това, е да поддържате това, което понякога се нарича a флаг байт. Някои приложения, особено тези, написани на езици с ниско ниво като асемблер, ще поддържат осем булеви флага в един байт. Например регистърът на състоянието на процесор 6502 чип съхранява тази информация в един 8-битов байт:
Бит 7. Отрицателно знаме
Бит 6. Флаг за преливане
Бит 5. неизползван
Бит 4. Разбийте знамето
Бит 3. Десетичен флаг
Бит 2. Прекъсване-деактивиране на флаг
Бит 1. Нулев флаг
Бит 0. Носете знаме
(от Уикипедия)
Ако вашият код трябва да работи с този вид данни, имате нужда от код за манипулация на битове с общо предназначение. Този код ще свърши работа!
„Подчиненият ClearBit изчиства 1 базиран, n-ти бит
'(MyBit) на цяло число (MyByte).
Sub ClearBit (ByRef MyByte, ByVal MyBit)
Dim BitMask като Int16
„Създайте битмаска с бита 2 до n-та мощност:
BitMask = 2 ^ (MyBit - 1)
„Изчисти деветия бит:
MyByte = MyByte, а не BitMask
Край Sub
„Функцията ExamineBit ще върне True или False
'в зависимост от стойността на базиран на 1-ти бит (MyBit)
'на цяло число (MyByte).
Функция ExamineBit (ByVal MyByte, ByVal MyBit) като Boolean
Dim BitMask като Int16
BitMask = 2 ^ (MyBit - 1)
ExamineBit = ((MyByte и BitMask)> 0)
Крайна функция
„SubBit Set ще зададе 1-ти, n-ти бит
'(MyBit) на цяло число (MyByte).
Sub SetBit (ByRef MyByte, ByVal MyBit)
Dim BitMask като Int16
BitMask = 2 ^ (MyBit - 1)
MyByte = MyByte или BitMask
Край Sub
„Подточката ToggleBit ще промени състоянието
'от 1 базиран, n-ти бит (MyBit)
'на цяло число (MyByte).
Sub ToggleBit (ByRef MyByte, ByVal MyBit)
Dim BitMask като Int16
BitMask = 2 ^ (MyBit - 1)
MyByte = MyByte Xor BitMask
Край Sub
За да демонстрира кода, тази рутина го извиква (параметри не са кодирани в Click Sub):
Частен Sub ExBitCode_Click (...
Dim Byte1, Byte2 As Byte
Dim MyByte, MyBit
Dim StatusOfBit As Boolean
Dim SelectedRB като низ
StatusLine. Текст = ""
ИзбраноRB = GetCheckedRadioButton (Me) .Name
Byte1 = ByteNum. Текст „Номер за преобразуване в битови флагове
Byte2 = BitNum. Текст „Бит за превключване
„Следното изчиства байта от висок ред и връща само
'байт с нисък ред:
MyByte = Byte1 И & HFF
MyBit = Байт2
Изберете Case SelectedRB
Дело "ClearBitButton"
ClearBit (MyByte, MyBit)
StatusLine. Text = "Нов байт:" & MyByte
Дело "ExamineBitButton"
StatusOfBit = ExamineBit (MyByte, MyBit)
StatusLine. Text = "Бит" & MyBit & _
"е" & StatusOfBit
Калъф "SetBitButton"
SetBit (MyByte, MyBit)
StatusLine. Text = "Нов байт:" & MyByte
Дело "ToggleBitButton"
ToggleBit (MyByte, MyBit)
StatusLine. Text = "Нов байт:" & MyByte
Избор на край
Край Sub
Частна функция GetCheckedRadioButton (_
ByVal родител като контрол) _
Като RadioButton
Dim FormControl като контрол
Dim RB като RadioButton
За всеки FormControl в родител. Контроли
Ако FormControl. GetType () е GetType (RadioButton) след това
RB = DirectCast (FormControl, RadioButton)
Ако RB.проверен, тогава върнете RB
Край Ако
Следващия
Върнете нищо
Крайна функция
Кодът в действие изглежда така:
Щракнете тук, за да покажете илюстрацията
Щракнете върху бутона Назад в браузъра си, за да се върнете