Cik Viegli Ir Aprēķināt CRC Kontrolsummu (CRC32 - CRC16 - CRC8)

Satura rādītājs:

Cik Viegli Ir Aprēķināt CRC Kontrolsummu (CRC32 - CRC16 - CRC8)
Cik Viegli Ir Aprēķināt CRC Kontrolsummu (CRC32 - CRC16 - CRC8)

Video: Cik Viegli Ir Aprēķināt CRC Kontrolsummu (CRC32 - CRC16 - CRC8)

Video: Cik Viegli Ir Aprēķināt CRC Kontrolsummu (CRC32 - CRC16 - CRC8)
Video: 57. CRC алгоритм (Урок 48. Теория) 2024, Novembris
Anonim

CRC kontrolsummas aprēķināšanai internetā ir daudz iespēju. Bet kas īsti ir kontrolsumma un kāpēc tā tiek aprēķināta šādā veidā? Izdomāsim.

Cik viegli ir aprēķināt CRC kontrolsummu (CRC32 - CRC16 - CRC8)
Cik viegli ir aprēķināt CRC kontrolsummu (CRC32 - CRC16 - CRC8)

Instrukcijas

1. solis

Pirmkārt, pieņemsim mazliet teorijas. Kas tad īsti ir CRC? Īsāk sakot, šī ir viena no kontrolsummas aprēķināšanas šķirnēm. Kontrolsumma ir metode, kā pārbaudīt saņemtās informācijas integritāti uztvērēja pusē, pārsūtot pa sakaru kanāliem. Piemēram, viena no vienkāršākajām pārbaudēm ir izmantot paritātes bitu. Tas ir, kad visi pārsūtītā ziņojuma biti tiek summēti, un, ja summa izrādās vienmērīga, tad ziņojuma beigām 0 tiek pievienots 0, ja tas ir nepāra, tad 1. Saņemot, tiek skaitīti arī ziņu biti un salīdzināti ar saņemto paritātes bitu. Ja tie atšķiras, tad pārsūtīšanas laikā radās kļūdas, un pārsūtītā informācija tika sagrozīta.

Bet šī kļūdu klātbūtnes noteikšanas metode ir ļoti neinformatīva un ne vienmēr darbojas, jo ja tiek sagrozīti vairāki ziņojuma biti, summas paritāte var nemainīties. Tāpēc ir daudz vairāk "uzlabotu" pārbaužu, ieskaitot CRC.

Patiesībā CRC nav summa, bet rezultāts, sadalot noteiktu informācijas daudzumu (informācijas ziņojumu) ar konstanti, pareizāk sakot, atlikušo daļu dalot ar konstanti. Tomēr CRC vēsturiski tiek saukta arī par "kontrolsummu". Katrs ziņojuma bits veicina CRC vērtību. Tas ir, ja pārsūtīšanas laikā mainās vismaz viens sākotnējā ziņojuma bits, mainīsies arī kontrolsumma un ievērojami. Tas ir liels šādas pārbaudes plus, jo tas ļauj nepārprotami noteikt, vai sākotnējais ziņojums sūtīšanas laikā ir sagrozīts vai nē.

2. solis

Pirms mēs sākam aprēķināt CRC, ir nepieciešama nedaudz vairāk teorijas.

Kādam sākotnējam ziņojumam jābūt skaidram. Tā ir blakus esoša patvaļīga garuma bitu secība.

Kas ir konstante, ar kuru mums jāsadala sākotnējais ziņojums? Šis skaitlis ir arī jebkura garuma, taču parasti tiek izmantoti 1 baita daudzkārtņi - 8, 16 un 32 biti. Skaitīt ir vienkārši vieglāk, jo datori strādā ar baitiem, nevis ar bitiem.

Dalītāja konstante parasti tiek rakstīta kā polinoms (polinoms) šādi: x ^ 8 + x ^ 2 + x ^ 1 + x ^ 0. Šeit skaitļa "x" pakāpe nozīmē viena bita pozīciju skaitlim, sākot no nulles, un visnozīmīgākais bits norāda polinoma pakāpi un tiek izmests, interpretējot skaitli. Tas ir, iepriekš uzrakstītais skaitlis ir nekas vairāk kā (1) 00000111 binārā vai 7 aiz komata. Iekavās es norādīju netieši nozīmīgāko skaitļa ciparu.

Šeit ir vēl viens piemērs: x ^ 16 + x ^ 15 + x ^ 2 + x ^ 0 = (1) 1000000000000101 = 0x8005 = 32773.

Dažādu tipu CRC parasti izmanto dažus standarta polinomus.

3. solis

Tātad, kā jūs aprēķināt kontrolsummu? Lai samazinātu aprēķinu skaitu un attiecīgi paātrinātu CRC aprēķinu, ir pamatmetode - ziņu sadalīšana polinomā “head-on” - un tās modifikācijas. Mēs izskatīsim pamata metodi.

Parasti skaitļa dalīšanu ar polinomu veic saskaņā ar šādu algoritmu:

1) tiek izveidots masīvs (reģistrs), kas piepildīts ar nullēm, vienāda garuma ar polinoma platuma garumu;

2) sākotnējais ziņojums tiek papildināts ar nullēm vismazāk nozīmīgajos bitos tādā daudzumā, kas vienāds ar polinoma bitu skaitu;

3) viens nozīmīgākais ziņojuma bits tiek ievadīts reģistra maznozīmīgākajā bitā un viens bits tiek pārvietots no nozīmīgākā reģistra bita;

4) ja paplašinātais bits ir vienāds ar "1", tad biti tiek apgriezti (XOR darbība, ekskluzīva VAI) tajos reģistra bitos, kas atbilst polinomā esošajiem;

5) ja ziņojumā joprojām ir biti, pārejiet pie 3. darbības);

6) kad visi ziņojuma biti ienāca reģistrā un tika apstrādāti ar šo algoritmu, atlikusī sadalījuma daļa paliek reģistrā, kas ir CRC kontrolsumma.

Attēlā parādīts sākotnējās bitu secības sadalījums ar skaitli (1) 00000111 vai polinomu x ^ 8 + x ^ 2 + x ^ 1 + x ^ 0.

CRC aprēķina shematisks attēlojums
CRC aprēķina shematisks attēlojums

4. solis

Ir palikuši pāris papildu pieskārieni. Kā jūs, iespējams, pamanījāt, ziņojumu var sadalīt ar jebkuru skaitli. Kā to izvēlēties? CRC aprēķināšanai tiek izmantoti vairāki standarta polinomi. Piemēram, CRC32 var būt 0x04C11DB7, bet CRC16 - 0x8005.

Turklāt reģistrā aprēķina sākumā varat ierakstīt nevis nulles, bet kādu citu skaitli.

Arī aprēķinu laikā, tieši pirms CRC galīgās kontrolsummas izdošanas, tos var sadalīt ar kādu citu skaitli.

Un pēdējā lieta. Rakstot reģistram, ziņojuma baitus var ievietot kā nozīmīgāko bitu "uz priekšu" un otrādi - vismazāk nozīmīgo bitu.

5. solis

Pamatojoties uz visu iepriekš minēto, uzrakstīsim Basic. NET funkciju, kas aprēķina CRC kontrolsummu, ņemot vairākus iepriekš aprakstītos parametrus un atgriežot CRC vērtību kā 32 bitu neparakstītu skaitli.

Publiska koplietojama funkcija GetCrc (ByVal baiti kā baits (), ByVal poli kā UInteger, pēc izvēles ByVal platums kā veselais skaitlis = 32, pēc izvēles ByVal initReg kā UInteger = & HFFFFFFFFUI, pēc izvēles ByVal finalXor kā UInteger = & HFFFFFFalFal, Reverse By, pēc izvēles reverseCrc As Būla = True) Kā UInteger

Blāvuma platumsInBytes As Integer = platums / 8

Papildiniet ziņojuma platumu ar nullēm (aprēķins baitos):

ReDim Saglabāt baitus (baiti. Garums - 1 + widthInBytes)

'Izveidojiet mazliet rindu no ziņojuma:

Dim msgFifo kā jauna rinda (no Būla) (baiti. Skaits * 8 - 1)

Katram b kā baits baitos

Dim ba kā jauns BitArray ({b})

Ja reverseBytes Tad

Par i kā vesels skaitlis = 0 līdz 7

msgFifo. Enqueue (ba (i))

Nākamais

Cits

Par i kā vesels skaitlis = 7 līdz 0 -1. Solis

msgFifo. Enqueue (ba (i))

Nākamais

Beigt Ja

Nākamais

'Izveidojiet rindu no reģistra sākotnējiem aizpildīšanas bitiem:

Dim initBytes kā baits () = BitConverter. GetBytes (initReg)

Dim initBytesReversed as IEnumerable (Of Byte) = (No b kā Byte In InitBytes ņem widthInBytes). Reverss

Dim initFifo kā jauna rinda (no Būla) (platums - 1)

Katram b kā baits initBytesReversed

Dim ba kā jauns BitArray ({b})

Ja nav reverseBytes Tad

Par i kā vesels skaitlis = 0 līdz 7

initFifo. Enqueue (ba (i))

Nākamais

Cits

Par i kā vesels skaitlis = 7 līdz 0 -1. Solis

initFifo. Enqueue (ba (i))

Nākamais

Beigt Ja

Nākamais

'Shift un XOR:

Aptumšot reģistru Tā kā UInteger = 0 ', aizpildiet platuma bitu reģistru ar nullēm.

Dariet, kamēr msgFifo. Count> 0

Dim poppedBit As Integer = CInt (reģistrēties >> (platums - 1)) un 1 'definēt pirms maiņu reģistra.

Dim shiftedBit kā baits = Convert. ToByte (msgFifo. Dequeue)

Ja initFifo. Count> 0 Tad

Dim b kā baits = Convert. ToByte (initFifo. Dequeue)

shiftedBit = shiftedBit Xor b

Beigt Ja

reģistrēties = reģistrēties << 1

register = register Vai shiftedBit

Ja poppedBit = 1 Tad

register = reģistrēt Xor poly

Beigt Ja

Loop

'Pēdējie reklāmguvumi:

Dim crc As UInteger = register 'Reģistrā ir atlikusī dalījuma == kontrolsumma daļa.

Ja reverseCrc Tad

crc = atstarot (crc, platums)

Beigt Ja

crc = crc Xor finalXor

crc = crc Un (& HFFFFFFFFUU >> (32 - platums)) 'maskē vismazāk nozīmīgos bitus.

Atgriezties crc

Beigu funkcija

Ieteicams: