VB.NET nie obsługuje bezpośrednio operacji na poziomie bitów. Framework 1.1 (VB.NET 2003) wprowadził operatorów przesunięcia bitów (<< i >>), ale nie jest dostępny ogólny sposób manipulowania poszczególnymi bitami. Operacje bitowe mogą być bardzo przydatnym. Na przykład Twój program może wymagać połączenia z innym systemem, który wymaga manipulacji bitami. Ale ponadto istnieje wiele sztuczek, które można wykonać przy użyciu poszczególnych bitów. W tym artykule opisano, co można zrobić za pomocą manipulacji bitami za pomocą VB.NET.
Musisz to zrozumieć operatory bitowe przed czymkolwiek innym. W VB.NET są to:
- I
- Lub
- Xor
- Nie
Bitowa oznacza po prostu, że operacje mogą być wykonywane na dwóch liczbach binarnych bit po bicie. Microsoft używa tabele prawdy do dokumentowania operacji bitowych. Tabela prawdy dla I jest:
1st bit 2nd bit Wynik
1 1 1
1 0 0
0 1 0
0 0 0
W mojej szkole uczyli Karnaugh zamiast tego mapy. Mapa Karnaugh dla wszystkich czterech operacji pokazano na poniższej ilustracji.
Kliknij tutaj, aby wyświetlić ilustrację
Kliknij przycisk Wstecz w przeglądarce, aby powrócić
Oto prosty przykład z użyciem I operacja na dwu, czterobitowych liczbach binarnych:
Wynik 1100 I 1010 to 1000.
To dlatego, że 1 I 1 to 1 (pierwszy bit), a reszta to 0.
Na początek spójrzmy na operacje bitowe, które są bezpośrednio obsługiwane w VB.NET: trochę się zmienia. Chociaż dostępne są zarówno lewe przesunięcie, jak i prawe przesunięcie, działają one w ten sam sposób, więc omawiane będą tylko lewe przesunięcie. Przesunięcie bitów jest najczęściej stosowane w kryptografii, przetwarzaniu obrazu i komunikacji.
Operacje przesuwania bitów w VB.NET ...
- Działa tylko z czterema typami liczb całkowitych: Bajt, Krótki, Liczba całkowita, i Długo
- Są arytmetyka operacje zmiany biegów. Oznacza to, że bity przesunięte poza koniec wyniku są wyrzucane, a pozycje bitów otwarte na drugim końcu są ustawiane na zero. Alternatywa nazywa się okrągłym przesunięciem bitów, a bity przesunięte poza jeden koniec są po prostu dodawane do drugiego. VB.NET nie obsługuje bezpośrednio przesunięcia bitów kołowych. Jeśli potrzebujesz, musisz zakodować go w staromodny sposób: pomnożenie lub podzielenie przez 2.
- Nigdy nie generuj wyjątku przepełnienia. VB.NET zajmuje się wszelkimi możliwymi problemami, a pokażę ci, co to oznacza. Jak wspomniano, możesz zakodować własne przesunięcie bitów, mnożąc lub dzieląc przez 2, ale jeśli używasz podejście „koduj własne”, musisz przetestować wyjątki przepełnienia, które mogą powodować twój program wypadek.
Standardowa operacja przesuwania bitów wyglądałaby mniej więcej tak:
Przyciemnij wartość początkową jako liczbę całkowitą = 14913080
Dim ValueAfterShifting As Integer
ValueAfterShifting = wartość początkowa << 50
Innymi słowy, ta operacja przyjmuje wartość binarną 0000 0000 1110 0011 1000 1110 0011 1000 (14913080 jest równoważną wartością dziesiętną - zauważ, że to tylko seria 3 0 i 3 1 powtórzonych kilka razy) i przesuwa ją o 50 miejsc w lewo. Ale ponieważ liczba całkowita ma tylko 32 bity, przesunięcie jej o 50 miejsc jest bez znaczenia. VB.NET rozwiązuje ten problem przez maskowanie liczba przesunięć ze standardową wartością, która odpowiada używanemu typowi danych. W tym przypadku, ValueAfterShifting jest Liczba całkowita więc maksimum, które można przesunąć, wynosi 32 bity. Standardowa wartość maski, która działa, to 31 miejsc po przecinku lub 11111.
Maskowanie oznacza, że wartość, w tym przypadku 50, wynosi Ied z maską. Daje to maksymalną liczbę bitów, które można faktycznie przesunąć dla tego typu danych.
W systemie dziesiętnym:
50 i 31 jest 18 - Maksymalna liczba bitów, które można przesunąć
W rzeczywistości ma to większy sens w systemie binarnym. Bity wysokiego rzędu, których nie można użyć do operacji zmiany biegów, są po prostu usuwane.
110010 i 11111 jest 10010
Gdy fragment kodu jest wykonywany, wynikiem jest 954204160 lub, binarnie, 0011 1000 1110 0000 0000 0000 0000 0000. 18 bitów po lewej stronie pierwszej liczby binarnej jest przesuniętych, a 14 bitów po prawej stronie przesuniętych w lewo.
Innym dużym problemem związanym z przesuwaniem bitów jest to, co dzieje się, gdy liczba miejsc do przesunięcia jest liczbą ujemną. Użyjmy -50 jako liczby bitów do przesunięcia i zobaczmy, co się stanie.
ValueAfterShifting = wartość początkowa << -50
Kiedy ten fragment kodu jest wykonywany, otrzymujemy -477233152 lub 1110 0011 1000 1110 0000 0000 0000 0000 w formacie binarnym. Liczba została przesunięta o 14 miejsc. Dlaczego 14? VB.NET zakłada, że liczba miejsc jest liczbą całkowitą bez znaku i robi I operacja z tą samą maską (31 dla liczb całkowitych).
1111 1111 1111 1111 1111 1111 1100 1110
0000 0000 0000 0000 0000 0000 0001 1111
(I)
0000 0000 0000 0000 0000 0000 0000 1110
1110 w systemie binarnym ma 14 miejsc po przecinku. Zauważ, że jest to odwrotność przesunięcia dodatnich 50 miejsc.
Na następnej stronie przechodzimy do innych operacji bitowych, zaczynając od Szyfrowanie Xor!
Wspomniałem, że jednym z zastosowań operacji bitowych jest szyfrowanie. Szyfrowanie Xor jest popularnym i prostym sposobem „szyfrowania” pliku. W moim artykule Bardzo proste szyfrowanie przy użyciu VB.NET pokazuję lepszy sposób używania manipulacji ciągami. Ale szyfrowanie Xor jest tak powszechne, że zasługuje przynajmniej na wyjaśnienie.
Szyfrowanie ciągu tekstowego oznacza przetłumaczenie go na inny ciąg tekstowy, który nie ma oczywistego związku z pierwszym. Potrzebujesz również sposobu, aby ponownie go odszyfrować. Szyfrowanie Xor tłumaczy binarny kod ASCII dla każdego znaku w ciągu na inny znak przy użyciu operacji Xor. Aby wykonać to tłumaczenie, potrzebujesz innego numeru do użycia w Xor. Ten drugi numer nazywa się kluczem.
Szyfrowanie Xor nazywa się „algorytmem symetrycznym”. Oznacza to, że możemy użyć klucza szyfrowania jako klucza deszyfrowania.
Użyjmy „A” jako klucza i zaszyfrujmy słowo „Podstawowy”. Kod ASCII dla „A” to:
0100 0001 (liczba dziesiętna 65)
Kod ASCII dla Basic to:
B - 0100 0010
a - 0110 0001
s - 0111 0011
i - 0110 1001
c - 0110 0011
The Xor z każdego z nich jest:
0000 0011 - dziesiętny 3
0010 0000 - dziesiętnie 32
0011 0010 - dziesiętnie 50
0010 1000 - dziesiętnie 40
0010 0010 - dziesiętny 34
Ta mała rutyna rozwiązuje problem:
- Szyfrowanie Xor -
Dim i As Short
ResultString. Text = „”
Dim KeyChar As Integer
KeyChar = Asc (EncryptionKey. Tekst)
For i = 1 To Len (InputString. Tekst)
ResultString. Tekst i = _
Chr (KeyChar Xor _
Asc (Mid (InputString. Tekst, i, 1)))
Kolejny
Wynik można zobaczyć na tej ilustracji:
Kliknij tutaj, aby wyświetlić ilustrację
Kliknij przycisk Wstecz w przeglądarce, aby powrócić
Aby odwrócić szyfrowanie, po prostu skopiuj i wklej ciąg z wyników TextBox z powrotem do String TextBox i ponownie kliknij przycisk.
Innym przykładem czegoś, co można zrobić z bitowymi operatorami, jest zamiana dwóch liczb całkowitych bez deklarowania trzeciej zmiennej do tymczasowego przechowywania. Tego właśnie robili lata temu w programach do asemblera. Nie jest to teraz zbyt przydatne, ale możesz kiedyś wygrać zakład, jeśli znajdziesz kogoś, kto nie wierzy, że możesz to zrobić. W każdym razie, jeśli nadal masz pytania dotyczące tego, jak Xor działa, praca przez to powinna ich uspokoić. Oto kod:
Dim FirstInt As Integer
Dim SecondInt As Integer
FirstInt = CInt (FirstIntBox. Tekst)
SecondInt = CInt (SecondIntBox. Tekst)
FirstInt = FirstInt Xor SecondInt
SecondInt = FirstInt Xor SecondInt
FirstInt = FirstInt Xor SecondInt
ResultBox. Text = „Pierwsza liczba całkowita:” i _
FirstInt. ToString i „-” i _
„Druga liczba całkowita:” i _
SecondInt. ToString
A oto kod w akcji:
Kliknij tutaj, aby wyświetlić ilustrację
Kliknij przycisk Wstecz w przeglądarce, aby powrócić
Zrozumienie, dlaczego to działa, pozostanie jako „ćwiczenie dla ucznia”.
Na następnej stronie osiągamy cel: Ogólna manipulacja bitami
Chociaż te sztuczki są zabawne i edukacyjne, nadal nie mogą zastąpić ogólnej manipulacji bitami. Jeśli naprawdę zejdziesz do poziomu bitów, to czego chcesz, to sposób na sprawdzenie pojedynczych bitów, ustawienie ich lub zmianę. To jest prawdziwy kod, którego brakuje w .NET.
Być może brakuje go dlatego, że napisanie podprogramów, które osiągają to samo, nie jest trudne.
Typowym powodem, dla którego warto to zrobić, jest zachowanie czegoś, co czasami nazywane jest bajt flagi. Niektóre aplikacje, zwłaszcza te napisane w językach niskiego poziomu, takich jak asembler, będą obsługiwały osiem flag boolowskich w jednym bajcie. Na przykład rejestr stanu układu procesora 6502 przechowuje te informacje w jednym 8-bitowym bajcie:
Bit 7. Flaga negatywna
Bit 6. Flaga przepełnienia
Bit 5. Nie używany
Bit 4. Złam flagę
Bit 3. Flaga dziesiętna
Bit 2. Flaga przerywania wyłączania
Bit 1. Flaga zero
Bit 0. Noś flagę
(z Wikipedii)
Jeśli twój kod musi pracować z tego rodzaju danymi, potrzebujesz kodu do manipulacji bitami ogólnego przeznaczenia. Ten kod wykona zadanie!
„ClearBit Sub usuwa n-bit na podstawie 1
„(MyBit) liczby całkowitej (MyByte).
Sub ClearBit (ByRef MyByte, ByVal MyBit)
Dim BitMask As Int16
„Utwórz maskę bitową za pomocą zestawu 2 do n-tego zestawu bitów mocy:
BitMask = 2 ^ (MyBit - 1)
„Wyczyść n-ty bit:
MyByte = MyByte And Not BitMask
Napis końcowy
„Funkcja ExamineBit zwróci True lub False
'w zależności od wartości n-tego bitu opartego na 1 (MyBit)
'liczby całkowitej (MyByte).
Funkcja ExamineBit (ByVal MyByte, ByVal MyBit) Jako wartość logiczna
Dim BitMask As Int16
BitMask = 2 ^ (MyBit - 1)
ExamineBit = ((MyByte And BitMask)> 0)
Funkcja zakończenia
„SetBit Sub ustawi n-bit na podstawie 1
„(MyBit) liczby całkowitej (MyByte).
Sub SetBit (ByRef MyByte, ByVal MyBit)
Dim BitMask As Int16
BitMask = 2 ^ (MyBit - 1)
MyByte = MyByte Lub BitMask
Napis końcowy
„Przełącznik ToggleBit zmieni stan
'1-szego bitu (MyBit)
'liczby całkowitej (MyByte).
Sub ToggleBit (ByRef MyByte, ByVal MyBit)
Dim BitMask As Int16
BitMask = 2 ^ (MyBit - 1)
MyByte = MyByte Xor BitMask
Napis końcowy
Aby zademonstrować kod, ta procedura wywołuje go (parametry niekodowane w Click Sub):
Private Sub ExBitCode_Click (...
Dim Byte1, Byte2 As Byte
Dim MyByte, MyBit
Dim StatusOfBit As Boolean
Dim SelectedRB As String
StatusLine. Text = „”
SelectedRB = GetCheckedRadioButton (Me) .Name
Byte1 = ByteNum. Tekst „Liczba do konwersji na flagi bitowe
Byte2 = BitNum. Tekst „Bit do przełączenia
„Poniższy kod usuwa bajt wyższego rzędu i zwraca tylko
„bajt niskiego rzędu:
MyByte = Byte1 And & HFF
MyBit = Byte2
Wybierz Case SelectedRB
Sprawa „ClearBitButton”
ClearBit (MyByte, MyBit)
StatusLine. Text = „New Byte:” i MyByte
Sprawa „ExamineBitButton”
StatusOfBit = ExamineBit (MyByte, MyBit)
StatusLine. Text = „Bit” i MyBit i _
„is” i StatusOfBit
Sprawa „SetBitButton”
SetBit (MyByte, MyBit)
StatusLine. Text = „New Byte:” i MyByte
Przypadek „ToggleBitButton”
ToggleBit (MyByte, MyBit)
StatusLine. Text = „New Byte:” i MyByte
End Wybierz
Napis końcowy
Funkcja prywatna GetCheckedRadioButton (_
ByVal Parent As Control) _
Jako RadioButton
Dim FormControl As Control
Dim RB As RadioButton
Dla każdego FormControl w rodzicu. Sterownica
Jeśli FormControl. GetType () to GetType (RadioButton)
RB = DirectCast (FormControl, RadioButton)
Jeśli RB.Sprawdzono, to zwróć RB
End If
Kolejny
Nic nie zwracaj
Funkcja zakończenia
Kod w akcji wygląda następująco:
Kliknij tutaj, aby wyświetlić ilustrację
Kliknij przycisk Wstecz w przeglądarce, aby powrócić