Mennyire Egyszerű Kiszámolni A CRC Ellenőrző összeget (CRC32 - CRC16 - CRC8)

Tartalomjegyzék:

Mennyire Egyszerű Kiszámolni A CRC Ellenőrző összeget (CRC32 - CRC16 - CRC8)
Mennyire Egyszerű Kiszámolni A CRC Ellenőrző összeget (CRC32 - CRC16 - CRC8)

Videó: Mennyire Egyszerű Kiszámolni A CRC Ellenőrző összeget (CRC32 - CRC16 - CRC8)

Videó: Mennyire Egyszerű Kiszámolni A CRC Ellenőrző összeget (CRC32 - CRC16 - CRC8)
Videó: CRC error detection in embedded applications 2024, December
Anonim

Számos lehetőség van a CRC ellenőrző összeg kiszámítására az interneten. De mi is pontosan az ellenőrző összeg, és miért számítják ki így? Találjuk ki.

Mennyire egyszerű kiszámolni a CRC ellenőrző összeget (CRC32 - CRC16 - CRC8)
Mennyire egyszerű kiszámolni a CRC ellenőrző összeget (CRC32 - CRC16 - CRC8)

Utasítás

1. lépés

Először is vegyünk egy kis elméletet. Mi tehát pontosan a CRC? Röviden, ez az ellenőrző összeg kiszámításának egyik fajtája. Az ellenőrző összeg egy módszer a vett információk integritásának ellenőrzésére a vevő oldalon kommunikációs csatornákon történő továbbításkor. Például az egyik legegyszerűbb ellenőrzés a paritásbit használata. Ekkor összesítik az átvitt üzenet összes bitjét, és ha az összeg párosnak bizonyul, akkor az üzenet végéhez 0-t adunk, ha páratlan, akkor 1. Fogadásakor az üzenet összege az üzenetbiteket is megszámoljuk és összehasonlítjuk a vett paritásbitekkel. Ha eltérnek egymástól, akkor hibák történtek az átvitel során, és az átvitt információ torzult.

De ez a módszer a hibák jelenlétének észlelésére nagyon informatív és nem mindig működik, mert ha az üzenet több bitje torzul, az összeg paritása nem változhat. Ezért sokkal több "speciális" ellenőrzés van, beleértve a CRC-t is.

Valójában a CRC nem összeg, hanem annak eredménye, hogy egy bizonyos mennyiségű információt (információs üzenetet) elosztunk egy konstanssal, vagy inkább az üzenet elosztásával fennmaradó részével. A CRC-t azonban történelmileg "ellenőrző összegnek" is nevezik. Az üzenet minden bitje hozzájárul a CRC értékéhez. Vagyis ha az eredeti üzenet legalább egy bitje változik az átvitel során, akkor az ellenőrző összeg is változik, és jelentősen. Ez egy nagy plusz egy ilyen ellenőrzésnek, mivel lehetővé teszi, hogy egyértelműen meghatározza, hogy az eredeti üzenet torzult-e az átvitel során, vagy sem.

2. lépés

Mielőtt elkezdenénk számítani a CRC-t, egy kicsit több elméletre van szükség.

Mi az eredeti üzenet, világosnak kell lennie. Ez tetszőleges hosszúságú bitek összefüggő sorozata.

Mi az a konstans, amellyel fel kellene osztanunk az eredeti üzenetet? Ez a szám szintén bármilyen hosszúságú, de általában 1 bájt többszörösét használják - 8, 16 és 32 bit. Csak könnyebb megszámolni, mert a számítógépek bájttal dolgoznak, nem bitekkel.

Az osztóállandót általában polinomként (polinomként) írjuk így: x ^ 8 + x ^ 2 + x ^ 1 + x ^ 0. Itt az "x" szám mértéke az egy bit helyét jelenti a számban, nullától kezdve, a legjelentősebb bit pedig a polinom mértékét jelzi, és a szám értelmezésekor elvetésre kerül. Vagyis az előzőleg írt szám nem más, mint (1) 00000111 bináris formában, vagy 7 decimálisban. Zárójelben feltüntettem a szám implicit legjelentősebb számjegyét.

Itt van egy másik példa: x ^ 16 + x ^ 15 + x ^ 2 + x ^ 0 = (1) 1000000000000101 = 0x8005 = 32773.

Általában néhány szokásos polinomot használnak a különböző típusú CRC-khez.

3. lépés

Tehát hogyan számolja ki az ellenőrző összeget? Létezik egy alapvető módszer - az üzenet felosztása polinomra "front-on" - és annak módosításai a számítások számának csökkentése és ennek megfelelően a CRC számításának felgyorsítása érdekében. Megnézzük az alapvető módszert.

Általában a szám polinommal történő felosztását a következő algoritmus szerint hajtják végre:

1) létrejön egy tömb (regiszter), amely nullákkal van kitöltve, hossza megegyezik a polinom szélességének hosszával;

2) az eredeti üzenetet nullákkal egészítik ki a legkevésbé jelentős bitekben, a polinom bitjeinek számával megegyező mennyiségben;

3) az üzenet egy legjelentősebb bitjét a regiszter legkevésbé jelentő bitjébe írják be, és egy bitet a nyilvántartás legjelentősebb bitjéből;

4) ha a kibővített bit egyenlő "1" -vel, akkor a bitek megfordulnak (XOR művelet, kizárólagos OR) azokban a regiszterbitekben, amelyek megfelelnek a polinomban levőknek;

5) ha még mindig vannak bitek az üzenetben, folytassa a 3. lépéssel;

6) Amikor az üzenet összes bitje belépett a regiszterbe és ezen algoritmus feldolgozta őket, az osztás fennmaradó része a nyilvántartásban marad, ami a CRC ellenőrző összeg.

Az ábra szemlélteti az eredeti bitsorozat felosztását az (1) 00000111 számmal vagy az x ^ 8 + x ^ 2 + x ^ 1 + x ^ 0 polinommal.

A CRC számításának sematikus ábrázolása
A CRC számításának sematikus ábrázolása

4. lépés

Van még néhány további érintés. Mint észrevette, az üzenet tetszőleges számmal felosztható. Hogyan válasszuk ki? A CRC kiszámításához számos szabványos polinom létezik. Például a CRC32 esetében 0x04C11DB7, a CRC16 esetében pedig 0x8005 lehet.

Ezenkívül a számítás elején található regiszterbe nem nullákat írhat, hanem valamilyen más számot.

A számítások során, közvetlenül a végleges CRC ellenőrző összeg kiadása előtt, fel lehet őket osztani más számmal.

És az utolsó dolog. Az üzenet bájtjai, amikor a regiszterbe írnak, elhelyezhetők a legjelentősebb "előre" bitként, és fordítva, a legkevésbé jelentős bitként.

5. lépés

A fentiek alapján írjunk egy Basic. NET függvényt, amely kiszámítja a CRC ellenőrző összegét úgy, hogy számos olyan paramétert vesz fel, amelyet fent leírtam, és a CRC értékét 32 bites előjel nélküli számként adta vissza.

Nyilvános megosztott függvény GetCrc (ByVal bájtok byte-ként (), ByVal poly mint UInteger, Opcionális ByVal szélességek Integer = 32, Opcionális ByVal initReg As UInteger = & HFFFFFFFFUI, Opcionális ByVal finalXor As UInteger = & HFFFFFFalFal Berse, Opcionális By reverseCrc As Boolean = True) UInteger-ként

Dim widthInBytes As Integer = szélesség / 8

'Kiegészítse az üzenet szélességét nullákkal (számítás bájtban):

ReDim Bájtok megőrzése (bájtok. Hossz - 1 + szélességInBytes)

'Hozzon létre egy kis sort az üzenetből:

Dim msgFifo új várólistaként (logikai értékből) (bájtok száma * 8 - 1)

Minden b bájtra bájtban

Dim ba új BitArray-ként ({b})

Ha reverseBytes Akkor

Mert i As egész szám = 0 és 7 között

msgFifo. Enqueue (ba (i))

Következő

Más

Az i As egész szám = 7-től 0-ig -1

msgFifo. Enqueue (ba (i))

Következő

Vége Ha

Következő

'Hozzon létre egy sort a regiszter kezdeti kitöltő bitjeiből:

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

Dim initBytesReversed as IEnumerable (Of Byte) = (b-ből Byte-ként In InitBytes vegye a widthInBytes értéket).

Dim initFifo, mint új várólista (logikai értékből) (szélesség - 1)

Minden b bájtra az initBytesReversedben

Dim ba új BitArray-ként ({b})

Ha nem reverseBytes Akkor

Mert i As egész szám = 0 és 7 között

initFifo. Enqueue (ba (i))

Következő

Más

Az i As egész szám = 7-től 0-ig -1

initFifo. Enqueue (ba (i))

Következő

Vége Ha

Következő

„Shift és XOR:

Dim register Mivel UInteger = 0 'töltse ki a szélességű bites regisztert nullákkal.

Do while msgFifo. Count> 0

Dim poppedBit As Integer = CInt (regisztráció >> (szélesség - 1)) És 1 'határozza meg a shift regiszter előtt.

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

Ha az initFifo. Count> 0 Akkor

Dim b As Byte = Konvertálás ToByte (initFifo. Dequeue)

shiftedBit = shiftedBit Xor b

Vége Ha

regisztráció = regisztráció << 1

register = regisztráció Vagy shiftedBit

Ha poppedBit = 1 Akkor

regisztráció = regisztráció Xor poly

Vége Ha

Hurok

'Végső konverziók:

Dim crc As UInteger = register 'A regisztráció a == ellenőrző összeg maradékát tartalmazza.

Ha fordítottCrc Akkor

crc = visszaverődés (crc, szélesség)

Vége Ha

crc = crc Xor finalXor

crc = crc És (& HFFFFFFFFUU >> (32 - szélesség)) 'eltakarja a legkevésbé jelentős biteket.

Vissza crc

Funkció befejezése

Ajánlott: