Hvor Let Det Er At Beregne CRC-kontrolsummen (CRC32 - CRC16 - CRC8)

Indholdsfortegnelse:

Hvor Let Det Er At Beregne CRC-kontrolsummen (CRC32 - CRC16 - CRC8)
Hvor Let Det Er At Beregne CRC-kontrolsummen (CRC32 - CRC16 - CRC8)

Video: Hvor Let Det Er At Beregne CRC-kontrolsummen (CRC32 - CRC16 - CRC8)

Video: Hvor Let Det Er At Beregne CRC-kontrolsummen (CRC32 - CRC16 - CRC8)
Video: Cyclic Redundancy Check(CRC) example 2024, April
Anonim

Der er mange muligheder for beregning af CRC-kontrolsummen på Internettet. Men hvad er nøjagtigt et kontrolsum, og hvorfor beregnes det på denne måde? Lad os finde ud af det.

Hvor let det er at beregne CRC-kontrolsummen (CRC32 - CRC16 - CRC8)
Hvor let det er at beregne CRC-kontrolsummen (CRC32 - CRC16 - CRC8)

Instruktioner

Trin 1

Lad os først få en smule teori. Så hvad er CRC præcist? Kort sagt er dette en af varianterne af beregning af checksum. Kontrolsum er en metode til at kontrollere integriteten af den modtagne information på modtagersiden, når der sendes over kommunikationskanaler. For eksempel er en af de enkleste kontroller at bruge paritetsbiten. Dette er når alle bits i den transmitterede meddelelse opsummeres, og hvis summen viser sig at være jævn, tilføjes 0 til slutningen af meddelelsen, hvis den er ulige, så 1. Når du modtager, bliver summen af meddelelsesbits tælles også og sammenlignes med den modtagne paritetsbit. Hvis de adskiller sig, opstod der fejl under transmission, og de transmitterede oplysninger blev forvrænget.

Men denne metode til at detektere tilstedeværelsen af fejl er meget uinformativ og fungerer ikke altid, fordi hvis flere bits i meddelelsen er forvrænget, ændres summen muligvis ikke. Derfor er der mange flere "avancerede" checks, herunder CRC.

Faktisk er CRC ikke en sum, men resultatet af at dividere en bestemt mængde information (informationsmeddelelse) med en konstant, eller rettere, resten af at dividere en besked med en konstant. Imidlertid kaldes CRC historisk også som en "kontrolsum". Hver bit af meddelelsen bidrager til CRC-værdien. Det vil sige, at hvis mindst en bit af den oprindelige besked ændres under transmission, vil kontrolsummen også ændre sig og væsentligt. Dette er et stort plus af en sådan kontrol, da det giver dig mulighed for entydigt at afgøre, om den oprindelige besked var forvrænget under transmission eller ej.

Trin 2

Før vi begynder at beregne CRC, er der brug for lidt mere teori.

Hvad der er den oprindelige meddelelse skal være klar. Det er en sammenhængende sekvens af bits med vilkårlig længde.

Hvad er den konstante, hvormed vi skal dele den oprindelige besked? Dette tal har også en hvilken som helst længde, men der bruges normalt multipla på 1 byte - 8, 16 og 32 bits. Det er bare lettere at tælle, fordi computere arbejder med bytes, ikke med bits.

Divisorkonstanten skrives normalt som et polynom (polynom) som dette: x ^ 8 + x ^ 2 + x ^ 1 + x ^ 0. Her betyder graden af tallet "x" positionen af en-bit i tallet startende fra nul, og den mest betydningsfulde bit angiver graden af polynomet og kasseres, når tallet fortolkes. Det vil sige, det tidligere skrevne tal er intet mere end (1) 00000111 i binær eller 7 i decimal. I parentes angav jeg det antydede mest betydningsfulde tal i nummeret.

Her er et andet eksempel: x ^ 16 + x ^ 15 + x ^ 2 + x ^ 0 = (1) 1000000000000101 = 0x8005 = 32773.

Normalt bruges nogle standardpolynomer til forskellige typer CRC'er.

Trin 3

Så hvordan beregner du kontrolsummen? Der er en grundlæggende metode - opdeling af en besked i et polynom "head-on" - og dens ændringer for at reducere antallet af beregninger og følgelig fremskynde CRC-beregningen. Vi vil se på den grundlæggende metode.

Generelt udføres delingen af et tal med et polynom i henhold til følgende algoritme:

1) der oprettes en matrix (register), fyldt med nuller, der er lig med længden af polynombredden;

2) den oprindelige meddelelse suppleres med nuller i de mindst signifikante bits i en mængde svarende til antallet af bit i polynomet;

3) en mest signifikant bit af meddelelsen indtastes i den mindst signifikante bit af registret, og en bit flyttes fra den mest betydningsfulde bit af registret;

4) hvis den udvidede bit er lig med "1", så er bitene inverteret (XOR-operation, eksklusiv OR) i de registerbits, der svarer til dem i polynomet;

5) hvis der stadig er bits i meddelelsen, skal du gå til trin 3);

6) når alle bitene i meddelelsen trådte ind i registret og blev behandlet af denne algoritme, forbliver resten af divisionen i registret, som er CRC-kontrolsummen.

Figuren illustrerer delingen af den originale bitsekvens med tallet (1) 00000111 eller polynomet x ^ 8 + x ^ 2 + x ^ 1 + x ^ 0.

Skematisk gengivelse af CRC-beregning
Skematisk gengivelse af CRC-beregning

Trin 4

Der er et par ekstra hånd tilbage. Som du måske har bemærket, kan meddelelsen deles med et hvilket som helst tal. Hvordan vælger jeg det? Der er et antal standardpolynomer, der bruges til at beregne CRC. For eksempel kan det for CRC32 være 0x04C11DB7, og for CRC16 kan det være 0x8005.

Derudover kan du i registret i begyndelsen af beregningen ikke skrive nuller, men noget andet nummer.

Under beregninger kan de lige inden udstedelsen af den endelige CRC-kontrolsum divideres med et andet nummer.

Og den sidste ting. Bytes af meddelelsen, når du skriver til registret, kan placeres som den mest betydningsfulde bit "fremad", og omvendt, den mindst signifikante.

Trin 5

Baseret på alt det ovenstående, lad os skrive en Basic. NET-funktion, der beregner CRC-kontrolsummen ved at tage et antal parametre, som jeg beskrev ovenfor, og returnere CRC-værdien som et 32-bit usigneret nummer.

Offentlig delt funktion GetCrc (ByVal-byte som byte (), ByVal poly som heltal, valgfri byval-bredde som heltal = 32, valgfri ByVal-initReg som U-heltal = & HFFFFFFFFUI, valgfri ByVal finalXor som U-heltal = & HFFFFFFFFUI, Valgfri ByVal-omvendt byte, reverseCrc As Boolean = True) Som UInteger

Dim widthInBytes As Integer = width / 8

'Suppler beskedbredden med nuller (beregning i byte):

ReDim Bevar bytes (bytes. Længde - 1 + breddeInBytes)

'Opret en smule kø fra meddelelsen:

Dim msgFifo As New Queue (Of Boolean) (bytes. Count * 8-1)

For hver b som byte i byte

Dim ba som ny BitArray ({b})

Hvis reverseBytes Så

For jeg som heltal = 0 til 7

msgFifo. Enqueue (ba (i))

Næste

Andet

For i som heltal = 7 til 0 trin -1

msgFifo. Enqueue (ba (i))

Næste

Afslut Hvis

Næste

'Opret en kø fra de første udfyldningsbits i registret:

Dim initBytes As Byte () = BitConverter. GetBytes (initReg)

Dim initBytesReversed As IEnumerable (Of Byte) = (From b As Byte In initBytes Tag widthInBytes).

Dim initFifo som ny kø (af boolsk) (bredde - 1)

For hver b som byte i initBytesReversed

Dim ba som ny BitArray ({b})

Hvis ikke reverseBytes Så

For jeg som heltal = 0 til 7

initFifo. Enqueue (ba (i))

Næste

Andet

For i som heltal = 7 til 0 trin -1

initFifo. Enqueue (ba (i))

Næste

Afslut Hvis

Næste

'Skift og XOR:

Dim register Som UInteger = 0 'udfyld bredde-bit registeret med nuller.

Gør mens msgFifo. Count> 0

Dim poppedBit As Integer = CInt (register >> (bredde - 1)) Og 1 'defineres før skiftregister.

Dim shiftedBit As Byte = Convert. ToByte (msgFifo. Dequeue)

Hvis initFifo. Count> 0 Så

Dim b As Byte = Convert. ToByte (initFifo. Dequeue)

shiftedBit = shiftedBit Xeller b

Afslut Hvis

register = register << 1

register = register Eller shiftedBit

Hvis poppedBit = 1 Så

register = register Xor poly

Afslut Hvis

Sløjfe

'Endelige konverteringer:

Dim crc As UInteger = register 'Registeret indeholder resten af divisionen == kontrolsum.

Hvis reverseCrc Derefter

crc = reflekterer (crc, bredde)

Afslut Hvis

crc = crc Xeller endeligXor

crc = crc Og (& HFFFFFFFFUI >> (32 - bredde)) 'maskerer de mindst signifikante bits.

Retur crc

Afslut funktion

Anbefalede: