CRC kontrollsumma arvutamiseks Internetis on palju võimalusi. Mis aga on kontrollsumma ja miks see sellisel viisil arvutatakse? Mõelgem välja.
Juhised
Samm 1
Kõigepealt võtame natuke teooriat. Mis täpselt on CRC? Lühidalt öeldes on see kontrollsumma arvutamise üks sorte. Kontrollsumma on meetod vastuvõetud teabe terviklikkuse kontrollimiseks vastuvõtja poolel, kui edastatakse sidekanalite kaudu. Näiteks on üks lihtsamaid kontrolle pariteedibiti kasutamine. See on siis, kui kõik edastatud sõnumi bitid summeeritakse ja kui summa osutub paarisarvuks, lisatakse sõnumi lõppu 0, kui see on paaritu, siis 1. Vastuvõtmisel saadetakse sõnumi summa loetakse ka sõnumibitte ja võrreldakse neid saadud pariteedibittidega. Kui need erinevad, tekkisid edastamisel vead ja edastatud teave oli moonutatud.
Kuid see meetod vigade olemasolu tuvastamiseks on väga väheinformatiivne ja ei toimi alati, sest kui mitu sõnumi bitti on moonutatud, ei pruugi summa pariteet muutuda. Seetõttu on palju täpsemaid kontrolle, sealhulgas CRC.
Tegelikult ei ole CRC summa, vaid teatud teabe (infosõnumi) hulga jagamise tulemus konstandiga, õigemini sõnumi konstandiga jagamise ülejäänud osa. Kuid CRC-d nimetatakse ajalooliselt ka "kontrollsummaks". Iga sõnumi bitt annab CRC väärtusele panuse. See tähendab, et kui edastamise ajal muutub vähemalt üks algsõnumi bitt, muutub ka kontrollsumma ja seda oluliselt. See on sellise kontrolli suur pluss, kuna see võimaldab teil üheselt kindlaks teha, kas algne sõnum oli edastamise ajal moonutatud või mitte.
2. samm
Enne CRC arvutamise alustamist on vaja veel natuke teooriat.
Mis on algne sõnum, peaks olema selge. See on suvalise pikkusega bittide järjestus.
Mis on konstant, mille järgi peaksime algse sõnumi jagama? See arv on ka mis tahes pikkusega, kuid tavaliselt kasutatakse 1 baidi kordseid - 8, 16 ja 32 bitti. Seda on lihtsalt lihtsam lugeda, sest arvutid töötavad baitidega, mitte bitidega.
Jagajakonstand kirjutatakse tavaliselt polünoomina (polünoomina) nii: x ^ 8 + x ^ 2 + x ^ 1 + x ^ 0. Siin tähendab arvu "x" aste ühe biti asukohta numbris, alustades nullist, ja kõige olulisem bitt tähistab polünoomi astet ja arvu tõlgendamisel jäetakse kõrvale. See tähendab, et varem kirjutatud arv on midagi muud kui (1) 00000111 binaarses või 7 kümnendkohas. Sulgudes märkisin numbri kaudse kõige olulisema numbri.
Siin on veel üks näide: x ^ 16 + x ^ 15 + x ^ 2 + x ^ 0 = (1) 1000000000000101 = 0x8005 = 32773.
Tavaliselt kasutatakse erinevat tüüpi CRC-de jaoks mõnda standardset polünoomi.
3. samm
Kuidas siis kontrollsummat arvutada? On olemas põhimeetod - sõnumi jagamine polünoomiks "peaga" - ja selle muudatused, et vähendada arvutuste arvu ja vastavalt kiirendada CRC arvutamist. Vaatame põhimeetodit.
Üldiselt toimub arvu jagamine polünoomiga järgmise algoritmi järgi:
1) luuakse nullidega täidetud massiiv (register), mille pikkus võrdub polünoomi laiuse pikkusega;
2) algsõnumit täiendatakse nullidega vähemtähtsate bitidena, summas, mis võrdub polünoomi bitide arvuga;
3) üks sõnumi kõige olulisem bitti kantakse registri kõige vähem olulisse bitti ja üks bit liigutatakse registri kõige olulisemast bitist;
4) kui laiendatud bitt on võrdne väärtusega "1", siis pööratakse bitid ümber (XOR-operatsioon, eksklusiivne OR) nendes registribittides, mis vastavad polünoomi omadele;
5) kui teates on veel bitti, minge 3. sammu juurde;
6) kui kõik sõnumi bitid sisenesid registrisse ja neid töödeldi selle algoritmiga, jääb jaotuse ülejäänud osa registrisse, mis on CRC kontrollsumma.
Joonis illustreerib algse bitijada jagunemist numbri (1) 00000111 või polünoomi x ^ 8 + x ^ 2 + x ^ 1 + x ^ 0 järgi.
4. samm
Paar täiendavat puudutust on jäänud. Nagu olete märganud, saab sõnumi jagada mis tahes numbriga. Kuidas seda valida? CRC arvutamiseks kasutatakse mitmeid standardseid polünoome. Näiteks CRC32 puhul võib see olla 0x04C11DB7 ja CRC16 puhul 0x8005.
Lisaks võite arvutuse alguses olevasse registrisse kirjutada mitte nulli, vaid mõne muu numbri.
Samuti saab arvutuste ajal vahetult enne CRC lõpliku kontrollsumma väljastamist need jagada mõne muu numbriga.
Ja viimane asi. Registrisse kirjutades saab sõnumi baiti asetada kõige olulisemaks bitiks "edasi" ja vastupidi, kõige vähem oluliseks bitiks.
5. samm
Kõigest ülaltoodust lähtudes kirjutame Basic. NET-i funktsiooni, mis arvutab CRC kontrollsumma, võttes mitu ülaltoodud parameetrit ja tagastades CRC-väärtuse 32-bitise allkirjastamata numbrina.
Avalik ühiskasutusega funktsioon GetCrc (ByVali baidid baidina (), ByVal polü kui UInteger, valikuline ByVali laius täisarvuna = 32, valikuline ByVal initReg nimega UInteger = & HFFFFFFFFUI, valikuline ByVal finalXor As UInteger = & HFFFFFFalFal, Reverse By, valikuline By reverseCrc As Boolean = True) UIntegerina
Hämara laiusInBaitides täisarvuna = laius / 8
Täiendage sõnumi laiust nullidega (arvutus baitides):
ReDim Säilita baiti (baiti. Pikkus - 1 + laius baiti)
'Looge sõnumist natuke järjekorda:
Dim msgFifo uue järjekorrana (tõeväärtusest) (baidid. Kogus * 8 - 1)
Iga b kohta baidina baitides
Dim ba kui uus BitArray ({b})
Kui reverseBytes Siis
I i täisarvuna = 0 kuni 7
msgFifo. Enqueue (ba (i))
Järgmine
Muidu
I i täisarvuna = 7 kuni 0 samm -1
msgFifo. Enqueue (ba (i))
Järgmine
Lõpeta, kui
Järgmine
'Loo registri algsetest täitebittidest järjekord:
Hämardab initbyte baidina () = BitConverter. GetBytes (initReg)
Dim initBytesReversed as IEloendamatu (baidist) = (b-st baidina initBaitides võtke widthInBytes).
Dim initFifo uue järjekorrana (tõeväärtusest) (laius - 1)
Iga b kohta baidina initBytesReversed
Dim ba kui uus BitArray ({b})
Kui ei ole reverseBytes Siis
I i täisarvuna = 0 kuni 7
initFifo. Enqueue (ba (i))
Järgmine
Muidu
I i täisarvuna = 7 kuni 0 samm -1
initFifo. Enqueue (ba (i))
Järgmine
Lõpeta, kui
Järgmine
'Shift ja XOR:
Hämarregister Kui UInteger = 0 ', täida laiusbitiline register nullidega.
Tehke, kuni msgFifo. Count> 0
Dim poppedBit As Integer = CInt (register >> (laius - 1)) Ja 1 'defineerib enne vahetuste registrit.
Dim shiftedBit As Byte = teisendamine ToByte (msgFifo. Dequeue)
Kui initFifo. Count> 0 Siis
Dim b baidina = Convert. Tobyte (initFifo. Dequeue)
shiftedBit = shiftedBit Xor b
Lõpeta, kui
register = register << 1
register = register Või shiftedBit
Kui poppedBit = 1 Siis
register = registreeri Xor poly
Lõpeta, kui
Loop
'Lõplikud konversioonid:
Dim crc As UInteger = register 'Register sisaldab ülejäänud jaotuse == kontrollsummat.
Kui vastupidineCrc Siis
crc = peegeldama (crc, laius)
Lõpeta, kui
crc = crc Xor finalXor
crc = crc Ja (& HFFFFFFFFUU >> (32 - laius)) 'maskeerib kõige vähem olulisi bitte.
Tagasi crc
Funktsioon Lõpeta