Daar is baie opsies om die CRC-kontrolesom op die internet te bereken. Maar wat is 'n kontrolesom presies en waarom word dit so bereken? Laat ons dit uitvind.
Instruksies
Stap 1
Laat ons eers 'n bietjie teorie kry. So, wat is CRC presies? Kortom, dit is een van die variëteite van die berekening van die kontrolesom. Kontrolesom is 'n metode om die integriteit van die ontvangde inligting aan die ontvangerkant na te gaan wanneer dit oor kommunikasiekanale gestuur word. Een van die eenvoudigste tjeks is byvoorbeeld om die pariteitsbit te gebruik. Dit is wanneer al die stukkies van die versende boodskap saamgevat word, en as die som gelyk blyk te wees, dan word 0 aan die einde van die boodskap gevoeg, as dit vreemd is, dan 1. As u die som ontvang, boodskap stukkies word ook getel en vergelyk met die ontvang pariteitsbit. As dit verskil, het daar foute tydens die oordrag plaasgevind en is die versende inligting verdraai.
Maar hierdie metode om foute op te spoor, is baie oninformatief en werk nie altyd nie as verskeie stukkies van die boodskap verdraai word, kan die pariteit van die som moontlik nie verander nie. Daarom is daar baie meer "gevorderde" tjeks, insluitend CRC.
In werklikheid is CRC nie 'n som nie, maar die resultaat van die deel van 'n sekere hoeveelheid inligting (inligtingsboodskap) deur 'n konstante, of eerder die res van die deel van 'n boodskap deur 'n konstante. Die CRC word egter histories ook 'n 'kontrolesom' genoem. Elke bietjie van die boodskap dra by tot die CRC-waarde. Dit wil sê, as ten minste een bietjie van die oorspronklike boodskap tydens die versending verander, sal die kontrolesom ook verander en aansienlik. Dit is 'n groot pluspunt van so 'n tjek, want dit stel u in staat om ondubbelsinnig te bepaal of die oorspronklike boodskap tydens die versending verdraai is of nie.
Stap 2
Voordat ons begin om die CRC te bereken, is 'n bietjie meer teorie nodig.
Wat die oorspronklike boodskap is, moet duidelik wees. Dit is 'n aaneenlopende volgorde van stukkies met willekeurige lengte.
Wat is die konstante waarmee ons die oorspronklike boodskap moet verdeel? Hierdie getal het ook enige lengte, maar meestal word veelvoude van 1 byte gebruik - 8, 16 en 32 bis. Dit is net makliker om te tel, want rekenaars werk met bytes, nie met bits nie.
Die delerkonstante word gewoonlik as 'n polinoom (polinoom) soos volg geskryf: x ^ 8 + x ^ 2 + x ^ 1 + x ^ 0. Hier beteken die graad van die getal "x" die posisie van die een-bis in die getal, vanaf nul, en die belangrikste bietjie dui die graad van die polinoom aan en word weggegooi wanneer u die getal interpreteer. Dit wil sê, die voorheen geskrewe getal is niks meer nie as (1) 00000111 in binêre, of 7 in desimaal. Tussen hakies het ek die beduidendste syfer van die nommer aangedui.
Hier is nog 'n voorbeeld: x ^ 16 + x ^ 15 + x ^ 2 + x ^ 0 = (1) 1000000000000101 = 0x8005 = 32773.
Gewoonlik word sommige polinome gebruik vir verskillende soorte CRC's.
Stap 3
Hoe bereken u die kontrolesom? Daar is 'n basiese metode - om 'n boodskap in 'n polinoom 'kop-op' te verdeel - en die wysigings daarvan om die aantal berekeninge te verminder en om die CRC-berekening te bespoedig. Ons sal na die basiese metode kyk.
Oor die algemeen word die deling van 'n getal deur 'n polinoom volgens die volgende algoritme uitgevoer:
1) 'n skikking (register) word geskep, gevul met nulle, ewe lank aan die lengte van die polinoomwydte;
2) die oorspronklike boodskap word aangevul met nulle in die minste betekenisvolle bisse, in 'n hoeveelheid gelyk aan die aantal bisse van die polinoom;
3) een belangrikste stukkie van die boodskap word in die minste beduidende stukkie van die register ingevoer, en een stukkie word verskuif van die belangrikste stukkie van die register;
4) as die uitgebreide bit gelyk is aan "1", dan word die bisse omgekeer (XOR-werking, eksklusief OF) in die registerbits wat ooreenstem met die in die polinoom;
5) as daar nog stukkies in die boodskap is, gaan na stap 3);
6) wanneer al die stukkies van die boodskap in die register kom en deur hierdie algoritme verwerk word, bly die res van die afdeling in die register, dit is die CRC-kontrolesom.
Die figuur illustreer die verdeling van die oorspronklike bitreeks deur die getal (1) 00000111, of die polinoom x ^ 8 + x ^ 2 + x ^ 1 + x ^ 0.
Stap 4
Daar is nog 'n paar bykomstighede oor. Soos u miskien opgemerk het, kan die boodskap deur enige nommer gedeel word. Hoe om dit te kies? Daar is 'n aantal standaard polinome wat gebruik word om die CRC te bereken. Byvoorbeeld, vir CRC32 kan dit 0x04C11DB7 wees, en vir CRC16 kan dit 0x8005 wees.
Daarbenewens kan u nie nulle in die register aan die begin van die berekening skryf nie, maar 'n ander nommer.
Tydens berekeninge, onmiddellik voor die uitreiking van die finale CRC-kontrolesom, kan dit ook deur 'n ander nommer gedeel word.
En die laaste ding. Bytes van die boodskap as u na die register skryf, kan as die belangrikste bietjie "vorentoe" geplaas word, en andersom, die minste betekenisvolle.
Stap 5
Laat ons, gebaseer op al die bogenoemde, 'n basiese. NET-funksie skryf wat die CRC-kontrolesom bereken deur 'n aantal parameters te neem wat ek hierbo beskryf het en die CRC-waarde as 'n 32-bis-ongetekende nommer terug te gee.
Openbare gedeelde funksie GetCrc (ByVal-byte as byte (), ByVal-poly as heelgetal, opsionele byval-breedte as heelgetal = 32, opsioneel byval-inleiding reg as heelgetal = & HFFFFFFFFUI, opsioneel byval-finaleX of as heelgetal = & HFFFFFFFFUI, opsioneel byval-omgekeerde bytes, reverseCrc As Boolean = True) As UInteger
Dim widthInBytes As Integer = width / 8
'Vul die boodskapbreedte met nulle aan (berekening in grepe):
ReDim Bewaar bytes (bytes. Lengte - 1 + breedteInBytes)
'Skep 'n bietjie tou vanaf die boodskap:
Dim msgFifo As New Queue (Of Boolean) (bytes. Count * 8 - 1)
Vir elke b As Byte In bytes
Dim ba as nuwe BitArray ({b})
As reverseBytes Dan
Vir i as heelgetal = 0 tot 7
msgFifo. Enqueue (ba (i))
Volgende
Anders
Vir i As heelgetal = 7 tot 0 Stap -1
msgFifo. Enqueue (ba (i))
Volgende
Einde as
Volgende
'Skep 'n tou vanaf die aanvanklike vulstukke van die register:
Dim initBytes As Byte () = BitConverter. GetBytes (initReg)
Dim initBytesReversed as IEnumerable (Of Byte) = (From b As Byte In initBytes Neem breedteInBytes).
Dim initFifo As New Queue (Of Boolean) (breedte - 1)
Vir elke b as byte in initBytesReversed
Dim ba as nuwe BitArray ({b})
As dit nie reverseBytes is nie, dan
Vir i as heelgetal = 0 tot 7
initFifo. Enqueue (ba (i))
Volgende
Anders
Vir i As heelgetal = 7 tot 0 Stap -1
initFifo. Enqueue (ba (i))
Volgende
Einde as
Volgende
'Shift en XOR:
Dim register As UInteger = 0 'vul die breedte-bit register met nulle.
Doen terwyl msgFifo. Count> 0
Dim poppedBit As Integer = CInt (register >> (breedte - 1)) En 1 'definieer voor skofregister.
Dim shiftedBit As Byte = Convert. ToByte (msgFifo. Dequeue)
As initFifo. Count> 0 Dan
Dim b as byte = Convert. ToByte (initFifo. Dequeue)
shiftedBit = shiftedBit Xof b
Einde as
registreer = registreer << 1
registreer = registreer of verskuifBit
As poppedBit = 1 Dan
register = register Xor poly
Einde as
Lus
'Finale omskakelings:
Dim crc As UInteger = register 'Die register bevat die res van die afdeling == kontrolesom.
As omgekeerCrc Dan
crc = weerspieël (crc, breedte)
Einde as
crc = crc Xof finaleXor
crc = crc En (& HFFFFFFFFUI >> (32 - breedte)) 'masker die minste betekenisvolle stukkies.
Keer terug crc
Eindfunksie