Որքան հեշտ է հաշվարկել CRC ստուգման գումարը (CRC32 - CRC16 - CRC8)

Բովանդակություն:

Որքան հեշտ է հաշվարկել CRC ստուգման գումարը (CRC32 - CRC16 - CRC8)
Որքան հեշտ է հաշվարկել CRC ստուգման գումարը (CRC32 - CRC16 - CRC8)

Video: Որքան հեշտ է հաշվարկել CRC ստուգման գումարը (CRC32 - CRC16 - CRC8)

Video: Որքան հեշտ է հաշվարկել CRC ստուգման գումարը (CRC32 - CRC16 - CRC8)
Video: 57. CRC алгоритм (Урок 48. Теория) 2024, Ապրիլ
Anonim

Ինտերնետում CRC ստուգման գումարը հաշվարկելու բազմաթիվ տարբերակներ կան: Բայց կոնկրետ ի՞նչ է ստուգման գումարումը և ինչու է այն հաշվարկվում այս եղանակով: Եկեք հասկանանք:

Որքան հեշտ է հաշվարկել CRC ստուգման գումարը (CRC32 - CRC16 - CRC8)
Որքան հեշտ է հաշվարկել CRC ստուգման գումարը (CRC32 - CRC16 - CRC8)

Հրահանգներ

Քայլ 1

Նախ եկեք մի փոքր տեսություն ստանանք: Այսպիսով, ի՞նչ է իրականում CRC- ն: Մի խոսքով, սա ստուգիչ գումարի հաշվարկման տեսակներից մեկն է: Checksum- ը ստացողի կողմից ստացված տեղեկատվության ամբողջականությունը ստուգելու մեթոդ է հաղորդակցման կապուղիներով փոխանցելիս: Օրինակ, ամենապարզ ստուգումներից մեկը պարիտետային բիթի օգտագործումն է: Սա այն դեպքում, երբ փոխանցվող հաղորդագրության բոլոր բիթերն ամփոփվում են, և եթե պարզվում է, որ գումարը հավասար է, ապա հաղորդագրության վերջում ավելանում է 0-ը, եթե այն կենտ է, ապա 1. Ստանալիս `գումարի գումարը հաղորդագրության բիթերը նույնպես հաշվվում և համեմատվում են ստացված հավասարության բիթի հետ: Եթե դրանք տարբեր են, ապա փոխանցման ընթացքում սխալներ են տեղի ունեցել, և փոխանցվող տեղեկատվությունն աղավաղվել է:

Բայց սխալների առկայությունը հայտնաբերելու այս մեթոդը շատ ոչ տեղեկատվական է և միշտ չէ, որ գործում է, քանի որ եթե հաղորդագրության մի քանի կտոր աղավաղված է, գումարի հավասարությունը չի կարող փոխվել: Հետեւաբար, կան շատ ավելի «առաջադեմ» ստուգումներ, ներառյալ CRC:

Փաստորեն, CRC- ը գումար չէ, այլ որոշակի քանակությամբ տեղեկատվություն (տեղեկատվական հաղորդագրություն) հաստատունի բաժանելու արդյունք է, ավելի ճիշտ `հաղորդագրությունը հաստատունի վրա բաժանելու մնացորդ: Այնուամենայնիվ, CRC- ն պատմականորեն հիշատակվում է նաև որպես «ստուգման գումար»: Հաղորդագրության յուրաքանչյուր բիթը նպաստում է CRC արժեքին: Այսինքն, եթե փոխանցման ընթացքում փոխվի սկզբնական հաղորդագրության առնվազն մեկ բիտը, ապա ստուգման գումարը նույնպես կփոխվի, և էապես: Սա նման ստուգման մեծ գումարած է, քանի որ այն թույլ է տալիս միանշանակ որոշել `փոխանցման ընթացքում աղավաղված է բուն հաղորդագրությունը, թե ոչ:

Քայլ 2

Նախքան CRC- ի հաշվարկը սկսելը, անհրաժեշտ է մի փոքր ավելի շատ տեսություն:

Ո՞րն է նախնական հաղորդագրությունը, պետք է պարզ լինի: Դա կամայական երկարության բիթերի հարակից հաջորդականություն է:

Ո՞րն է այն հաստատունը, որով մենք պետք է բաժանենք սկզբնական հաղորդագրությունը: Այս թիվը նույնպես ունի ցանկացած երկարություն, բայց սովորաբար օգտագործվում են 1 բայտի բազմապատիկներ `8, 16 և 32 բիթ: Պարզապես հաշվելն ավելի հեշտ է, քանի որ համակարգիչներն աշխատում են բայթերով, ոչ թե բիտերով:

Բաժանիչ հաստատունը սովորաբար գրվում է որպես բազմանդամ (բազմանդամ) այսպես ՝ x ^ 8 + x ^ 2 + x ^ 1 + x ^ 0: Այստեղ «x» թվի աստիճանը նշանակում է թվի մեջ մեկ բիթի դիրքը `սկսած զրոյից, իսկ ամենանշանակալից բիտը ցույց է տալիս բազմանդամի աստիճանը և դուրս է մղվում թիվը մեկնաբանելիս: Այսինքն ՝ նախկինում գրված համարը ոչ այլ ինչ է, քան (1) 00000111 երկուական, կամ 7 տասնորդական: Փակագծերում ես նշեցի թվի ակնարկված ամենանշանակալի թվանշանը:

Ահա ևս մեկ օրինակ. X ^ 16 + x ^ 15 + x ^ 2 + x ^ 0 = (1) 100000000000010101 = 0x8005 = 32773:

Սովորաբար որոշ ստանդարտ բազմանդամներ օգտագործվում են տարբեր տեսակի CRC- ների համար:

Քայլ 3

Այսպիսով, ինչպե՞ս եք հաշվարկում ստուգման գումարը: Կա մի հիմնական մեթոդ `հաղորդագրությունը բաժանել« բազմակողմանի »« գլխի վրա »և դրա փոփոխությունները` հաշվարկների քանակը նվազեցնելու և, համապատասխանաբար, CRC հաշվարկը արագացնելու համար: Մենք կանդրադառնանք հիմնական մեթոդին:

Ընդհանուր առմամբ, թվերի բաժանումը բազմանդամով կատարվում է ըստ հետեւյալ ալգորիթմի.

1) ստեղծվում է զանգված (ռեգիստր), լցված զրոներով, երկարությամբ հավասար բազմանդամի լայնության երկարությանը.

2) սկզբնական հաղորդագրությունը լրացվում է զրոներով `նվազագույն նշանակալի բիթերով, բազմանդամի բիթերի քանակին հավասար քանակով.

3) հաղորդագրության մեկ ամենանշանակալից բիտը մուտքագրվում է ռեգիստրի նվազագույն նշանակալի բիթ, իսկ մեկ բիտը տեղափոխվում է ռեգիստրի ամենանշանակալի բիթից.

4) եթե ընդլայնված բիտը հավասար է «1» -ին, ապա բիթերը շրջվում են (XOR գործողություն, բացառիկ ԿԱՄ) այն ռեգիստրի բիթերում, որոնք համապատասխանում են բազմանդամի մեջ գտնվողներին.

5) եթե հաղորդագրության մեջ դեռ բիթեր կան, անցեք 3-րդ քայլին).

6) երբ հաղորդագրության բոլոր բիթերը գրանցում են մուտքագրվում և մշակվում են այս ալգորիթմով, բաժանման մնացած մասը մնում է գրանցամատյանում, որը CRC ստուգիչ գումարն է:

Նկարը պատկերում է բիտերի սկզբնական հաջորդականության բաժանումը (1) 00000111 թվով կամ x ^ 8 + x ^ 2 + x ^ 1 + x ^ 0 բազմանդամով:

CRC հաշվարկի սխեմատիկ ներկայացում
CRC հաշվարկի սխեմատիկ ներկայացում

Քայլ 4

Մնացել են մի քանի լրացուցիչ հպումներ: Ինչպես երևի նկատել եք, հաղորդագրությունը կարելի է բաժանել ցանկացած թվով: Ինչպե՞ս ընտրել այն: Գոյություն ունեն մի շարք ստանդարտ բազմանդամներ, որոնք օգտագործվում են CRC- ի հաշվարկման համար: Օրինակ, CRC32- ի համար կարող է լինել 0x04C11DB7, իսկ CRC16- ի համար `0x8005:

Բացի այդ, հաշվարկի սկզբում գրանցամատյանում կարող եք գրել ոչ թե զրոներ, այլ ինչ-որ այլ թիվ:

Բացի այդ, հաշվարկների ժամանակ, CRC- ի վերջնական ստուգիչ գումարը տալուց անմիջապես առաջ, դրանք կարող են բաժանվել ինչ-որ այլ համարի:

Եվ վերջին բանը: Գրանցամատյանում գրելու ժամանակ հաղորդագրության բայթերը կարող են դրվել որպես ամենաէական «բեռնաթափման» բիթ, և հակառակը ՝ ամենաքիչ նշանակությունը:

Քայլ 5

Ելնելով վերը նշված բոլորից ՝ եկեք գրենք Հիմնական. NET ֆունկցիա, որը հաշվարկում է CRC ստուգման գումարը ՝ վերցնելով վերը նկարագրվածս մի շարք պարամետրեր և վերադարձնելով CRC արժեքը որպես 32-բիթանոց անստորագիր համար:

GetCrc հանրային համօգտագործված ֆունկցիա reverseCrc As Boolean = True) Որպես UInteger

Dim widthInBytes As Integer = լայնություն / 8

«Հաղորդագրության լայնությունը լրացնել զրոներով (հաշվարկը բայթերով).

ReDim պահեք բայթերը (բայթ: Երկարություն - 1 + լայնությունInBytes)

«Հաղորդագրությունից մի փոքր հերթ ստեղծեք.

Dim msgFifo as New Queue (Of Boolean) (բայթեր. Հաշվիչ * 8 - 1)

Յուրաքանչյուր բ-ի համար, ինչպես բայթ ՝ բայթում

Dim ba as New BitArray ({b})

Եթե reverseBytes Ապա

For i As Integer = 0-ից 7

msgFifo. Enqueue (ba (i))

Հաջորդը

Ուրիշ

For i As Integer = 7-ից 0 քայլ -1

msgFifo. Enqueue (ba (i))

Հաջորդը

Վերջ եթե

Հաջորդը

«Գրանցման սկզբնական լրացումներից հերթ ստեղծել:

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

Dim initBytes Վերանայվում է որպես IEnumerable (բայթ) = (b- ից By byte in initBytes Վերցրեք widthInBytes): Հակադարձել

Dim initFifo As New Queue (Of Boolean) (լայնությունը ՝ 1)

Յուրաքանչյուր բ-ի համար, ինչպես byte In initBytesReversed

Dim ba as New BitArray ({b})

Եթե ոչ reverseBytes ապա

For i As Integer = 0-ից 7

initFifo. Enqueue (բա (ես))

Հաջորդը

Ուրիշ

For i As Integer = 7-ից 0 քայլ -1

initFifo. Enqueue (բա (ես))

Հաջորդը

Վերջ եթե

Հաջորդը

'Shift և XOR:

Dim գրանցումը որպես UInteger = 0 'լրացնում է լայնության բիթի գրանցամատյանը զրոներով:

Անել մինչ msgFifo. Count> 0

Dim poppedBit As Integer = CInt (գրանցում >> (լայնություն - 1)) Եվ 1 'սահմանել հերթափոխի գրանցումից առաջ:

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

Եթե initFifo. Count> 0 Ապա

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

shiftedBit = տեղափոխված Bit Xor բ

Վերջ եթե

գրանցում = գրանցում << 1

գրանցվել = գրանցվել կամ տեղափոխվել Bit

Եթե poppedBit = 1 Հետո

գրանցվել = գրանցվել Xor poly

Վերջ եթե

Օղակ

'Վերջնական փոխարկումներ.

Dim crc As UInteger = գրանցում »Գրանցամատյանը պարունակում է բաժանման մնացած մասը == ստուգման գումար:

Եթե reverseCrc Ապա

crc = արտացոլել (crc, լայնություն)

Վերջ եթե

crc = crc Xor վերջնական Xor

crc = crc And (& HFFFFFFFFUI >> (32 - լայնություն)) '' քողարկում է նվազագույն նշանակալի բիթերը:

Վերադարձնել CRC

Վերջ գործառույթ

Խորհուրդ ենք տալիս: