VB.NET biedt geen directe ondersteuning voor bitniveau-bewerkingen. Framework 1.1 (VB.NET 2003) introduceerde bit shift-operators (<< en >>), maar er is geen algemene manier om afzonderlijke bits te manipuleren beschikbaar. Bit operaties kan erg handig zijn. Uw programma moet bijvoorbeeld mogelijk communiceren met een ander systeem dat bitmanipulatie vereist. Maar daarnaast zijn er veel trucs die met afzonderlijke bits kunnen worden gedaan. Dit artikel geeft een overzicht van wat kan worden gedaan met bitmanipulatie met behulp van VB.NET.
Je moet het begrijpen bitsgewijze operatoren voor iets anders. In VB.NET zijn dit:
- En
- Of
- Xor
- Niet
Bitwise betekent gewoon dat de bewerkingen bit voor bit op twee binaire getallen kunnen worden uitgevoerd. Microsoft gebruikt waarheidstabellen om bitoperaties te documenteren. De waarheidstabel voor En is:
1e bit 2e bit resultaat
1 1 1
1 0 0
0 1 0
0 0 0
Op mijn school gaven ze les Karnaugh kaarten in plaats daarvan. De Karnaugh-kaart voor alle vier bewerkingen wordt weergegeven in de onderstaande afbeelding.
Klik hier om de afbeelding weer te geven
Klik op de knop Terug in uw browser om terug te keren
Hier is een eenvoudig voorbeeld met de En werking met twee, vier bit binaire getallen:
Het resultaat van 1100 En 1010 is 1000.
Dat komt omdat 1 En 1 is 1 (het eerste bit) en de rest is 0.
Laten we om te beginnen eens kijken naar de bitbewerkingen die zijn rechtstreeks ondersteund in VB.NET: beetje verschuivend. Hoewel zowel de linker shift als de rechter shift beschikbaar zijn, werken ze op dezelfde manier, zodat alleen de linker shift wordt besproken. Bit shifting wordt meestal gebruikt in cryptografie, beeldverwerking en communicatie.
Bit Shift-bewerkingen van VB.NET ...
- Werk alleen met de vier soorten gehele getallen: Byte, Kort, Geheel getalen Lang
- Zijn rekenkundig schakelhandelingen. Dat betekent dat bits die voorbij het einde van het resultaat zijn verschoven, worden weggegooid en de aan het andere einde geopende bitposities op nul worden gezet. Het alternatief wordt circulaire bitverschuiving genoemd en de bits die voorbij het ene uiteinde zijn verschoven, worden eenvoudig aan het andere toegevoegd. VB.NET ondersteunt niet direct circulair bitverschuiven. Als je het nodig hebt, moet je het op de ouderwetse manier coderen: vermenigvuldigen of delen door 2.
- Genereer nooit een overloopuitzondering. VB.NET zorgt voor mogelijke problemen en ik zal je laten zien wat dat betekent. Zoals opgemerkt, kunt u uw eigen bitverschuiving coderen door te vermenigvuldigen of delen door 2, maar als u de "codeer uw eigen" aanpak, moet u testen op overstromingsuitzonderingen die uw programma kunnen veroorzaken Botsing.
Een standaard bit-shift operatie zou er ongeveer zo uitzien:
Dim StartingValue As Integer = 14913080
Dim ValueAfterShifting As Integer
ValueAfterShifting = StartingValue << 50
In woorden neemt deze bewerking de binaire waarde aan 0000 0000 1110 0011 1000 1110 0011 1000 (14913080 is de equivalente decimale waarde - merk op dat het slechts een reeks van 3 0's en 3 1's is die enkele keren worden herhaald) en verschuift het 50 plaatsen naar links. Maar omdat een geheel getal slechts 32 bits lang is, heeft het 50 plaatsen verplaatsen zinloos. VB.NET lost dit probleem op door maskeren het aantal verschuivingen met een standaardwaarde die overeenkomt met het gegevenstype dat wordt gebruikt. In dit geval, ValueAfterShifting is een Geheel getal dus het maximum dat kan worden verschoven is 32 bits. De standaard maskeerwaarde die werkt is 31 decimaal of 11111.
Maskeren betekent dat de waarde, in dit geval 50, is Ened met het masker. Dit geeft het maximale aantal bits dat daadwerkelijk voor dat gegevenstype kan worden verschoven.
In decimaal:
50 en 31 is 18 - Het maximale aantal bits dat kan worden verschoven
Het is eigenlijk logischer in binair. De bits van hoge orde die niet kunnen worden gebruikt voor het schakelen, worden eenvoudig verwijderd.
110010 En 11111 is 10010
Wanneer het codefragment wordt uitgevoerd, is het resultaat 954204160 of, binair, 0011 1000 1110 0000 0000 0000 0000 0000 0000. De 18 bits aan de linkerkant van het eerste binaire getal zijn verschoven en de 14 bits aan de rechterkant zijn naar links verschoven.
Het andere grote probleem met verschuivende bits is wat er gebeurt als het aantal te verschuiven plaatsen een negatief getal is. Laten we -50 gebruiken als het aantal bits om te verschuiven en kijken wat er gebeurt.
ValueAfterShifting = StartingValue << -50
Wanneer dit codefragment wordt uitgevoerd, krijgen we -477233152 of 1110 0011 1000 1110 0000 0000 0000 0000 in binair. Het nummer is 14 plaatsen naar links verschoven. Waarom 14? VB.NET gaat ervan uit dat het aantal plaatsen een geheel getal zonder teken is en doet een En bewerking met hetzelfde masker (31 voor gehele getallen).
1111 1111 1111 1111 1111 1111 1100 1110
0000 0000 0000 0000 0000 0000 0001 1111
(En)
0000 0000 0000 0000 0000 0000 0000 1110
1110 in binair getal is 14 decimaal. Merk op dat dit het omgekeerde is van het verplaatsen van een positieve 50 plaatsen.
Op de volgende pagina gaan we verder met enkele andere bitbewerkingen, te beginnen met Xor-codering!
Ik heb gezegd dat één gebruik van bitbewerkingen codering is. Xor-codering is een populaire en eenvoudige manier om een bestand te "coderen". In mijn artikel Very Simple Encryption using VB.NET, laat ik je in plaats daarvan een betere manier zien met stringmanipulatie. Maar Xor-codering is zo gewoon dat het op zijn minst moet worden uitgelegd.
Het coderen van een tekstreeks betekent dat deze wordt vertaald in een andere tekstreeks die geen duidelijke relatie heeft met de eerste. Je hebt ook een manier nodig om het opnieuw te decoderen. Xor-codering vertaalt de binaire ASCII-code voor elk karakter in de string in een ander karakter met behulp van de Xor-bewerking. Om deze vertaling te doen, hebt u een ander nummer nodig om in de Xor te gebruiken. Dit tweede nummer wordt de sleutel genoemd.
Xor-codering wordt een "symmetrisch algoritme" genoemd. Dit betekent dat we de coderingssleutel ook als de decoderingssleutel kunnen gebruiken.
Laten we "A" als sleutel gebruiken en het woord "Basic" coderen. De ASCII-code voor "A" is:
0100 0001 (decimaal 65)
De ASCII-code voor Basic is:
B - 0100 0010
a - 0110 0001
s - 0111 0011
i - 0110 1001
c - 0110 0011
De Xor van elk van deze is:
0000 0011 - decimaal 3
0010 0000 - decimaal 32
0011 0010 - decimaal 50
0010 1000 - decimaal 40
0010 0010 - decimaal 34
Deze kleine routine volstaat:
- Xor encryptie -
Dim ik zo kort
ResultString. Text = ""
Dim KeyChar als geheel getal
KeyChar = Asc (EncryptionKey. Tekst)
Voor i = 1 tot Len (InputString. Tekst)
ResultString. Tekst & = _
Chr (KeyChar Xor _
Asc (Mid (InputString. Tekst, i, 1)))
De volgende
Het resultaat is te zien in deze illustratie:
Klik hier om de afbeelding weer te geven
Klik op de knop Terug in uw browser om terug te keren
Om de codering ongedaan te maken, kopieert en plakt u de string uit de TextBox van het resultaat terug in de TextBox String en klikt u nogmaals op de knop.
Een ander voorbeeld van iets dat u kunt doen met bitsgewijze operatoren is om twee gehele getallen te verwisselen zonder een derde variabele voor tijdelijke opslag te declareren. Dit is het soort dingen dat ze jaren geleden deden in assemblerprogramma's. Het is nu niet zo handig, maar je kunt ooit een weddenschap winnen als je iemand kunt vinden die niet gelooft dat je het kunt doen. In ieder geval als je nog vragen hebt over hoe Xor werkt, als je dit doorwerkt, zouden ze moeten rusten. Hier is de code:
Dim eerst als geheel getal
Dim SecondInt As Geheel getal
FirstInt = CInt (FirstIntBox. Tekst)
SecondInt = CInt (SecondIntBox. Tekst)
FirstInt = FirstInt Xor SecondInt
SecondInt = FirstInt Xor SecondInt
FirstInt = FirstInt Xor SecondInt
ResultBox. Text = "First Integer:" & _
FirstInt. ToString & "-" & _
"Tweede geheel getal:" & _
SecondInt. ToString
En hier is de code in actie:
Klik hier om de afbeelding weer te geven
Klik op de knop Terug in uw browser om terug te keren
Uitzoeken precies waarom dit werkt zal worden achtergelaten als "als een oefening voor de student".
Op de volgende pagina bereiken we het doel: algemene bitmanipulatie
Hoewel deze trucs leuk en leerzaam zijn, zijn ze nog steeds geen vervanging voor algemene bitmanipulatie. Als je echt op het niveau van bits komt, is wat je wilt een manier om individuele bits te onderzoeken, in te stellen of te wijzigen. Dat is de echte code die ontbreekt in .NET.
Misschien is de reden dat het ontbreekt, dat het niet zo moeilijk is om subroutines te schrijven die hetzelfde bereiken.
Een typische reden waarom u dit misschien wilt doen, is het handhaven van wat soms a wordt genoemd vlagbyte. Sommige toepassingen, vooral die geschreven in talen op laag niveau zoals assembler, behouden acht Booleaanse vlaggen in één byte. Het statusregister van een 6502 processorchip bevat deze informatie bijvoorbeeld in een enkele 8 bit byte:
Bit 7. Negatieve vlag
Bit 6. Overloop vlag
Bit 5. Ongebruikt
Bit 4. Vlag breken
Bit 3. Decimale vlag
Bit 2. Vlag onderbreken
Bit 1. Geen vlag
Bit 0. Vlag dragen
(van Wikipedia)
Als uw code met dit soort gegevens moet werken, heeft u algemene bitmanipulatiecode nodig. Deze code zal het werk doen!
'De ClearBit Sub wist het op 1 gebaseerde, nth-bit
'(MyBit) van een geheel getal (MyByte).
Sub ClearBit (ByRef MyByte, ByVal MyBit)
Dim BitMask As Int16
'Maak een bitmasker met de 2 tot en met de nde power bit set:
BitMask = 2 ^ (MyBit - 1)
'Wis het negende bit:
MyByte = MyByte en niet BitMask
Einde Sub
'De ExamineBit-functie retourneert Waar of Onwaar
'afhankelijk van de waarde van het op 1 gebaseerde, n-bit (MyBit)
'van een geheel getal (MyByte).
Functie ExamineBit (ByVal MyByte, ByVal MyBit) als Boolean
Dim BitMask As Int16
BitMask = 2 ^ (MyBit - 1)
ExamineBit = ((MyByte en BitMask)> 0)
Einde functie
'De SetBit Sub zal het op 1 gebaseerde, nth-bit instellen
'(MyBit) van een geheel getal (MyByte).
Sub SetBit (ByRef MyByte, ByVal MyBit)
Dim BitMask As Int16
BitMask = 2 ^ (MyBit - 1)
MyByte = MyByte of BitMask
Einde Sub
'De ToggleBit Sub verandert de status
'van het 1 gebaseerde, nde bit (MyBit)
'van een geheel getal (MyByte).
Sub ToggleBit (ByRef MyByte, ByVal MyBit)
Dim BitMask As Int16
BitMask = 2 ^ (MyBit - 1)
MyByte = MyByte Xor BitMask
Einde Sub
Om de code aan te tonen, noemt deze routine het (parameters niet gecodeerd op Click Sub):
Private Sub ExBitCode_Click (...
Dim Byte1, Byte2 As Byte
Dim MyByte, MyBit
Dim StatusOfBit As Boolean
Dim geselecteerdRB als tekenreeks
StatusLine. Text = ""
SelectedRB = GetCheckedRadioButton (Me) .Name
Byte1 = ByteNum. Tekst 'Nummer om te zetten in bitvlaggen
Byte2 = BitNum. Tekst 'Bit om te schakelen
'Het volgende wist de byte van hoge orde en retourneert alleen de
lage byte:
MyByte = Byte1 En & HFF
MyBit = Byte2
Selecteer geval geselecteerd
Case "ClearBitButton"
ClearBit (MyByte, MyBit)
StatusLine. Text = "New Byte:" & MyByte
Case "ExamineBitButton"
StatusOfBit = ExamineBit (MyByte, MyBit)
StatusLine. Text = "Bit" & MyBit & _
"is" & StatusOfBit
Case "SetBitButton"
SetBit (MyByte, MyBit)
StatusLine. Text = "New Byte:" & MyByte
Case "ToggleBitButton"
ToggleBit (MyByte, MyBit)
StatusLine. Text = "New Byte:" & MyByte
Einde selecteren
Einde Sub
Privéfunctie GetCheckedRadioButton (_
ByVal Parent As Control) _
Zoals RadioButton
Dim FormControl als controle
Dim RB als RadioButton
Voor elke FormControl in Parent. Bediening
Als FormControl. GetType () Is dan GetType (RadioButton)
RB = DirectCast (FormControl, RadioButton)
Als RB.Checked Dan Return RB
Stop als
De volgende
Niets teruggeven
Einde functie
De code in actie ziet er als volgt uit:
Klik hier om de afbeelding weer te geven
Klik op de knop Terug in uw browser om terug te keren