CRC Nəzarət Məbləğini Hesablamaq Nə Qədər Asandır (CRC32 - CRC16 - CRC8)

Mündəricat:

CRC Nəzarət Məbləğini Hesablamaq Nə Qədər Asandır (CRC32 - CRC16 - CRC8)
CRC Nəzarət Məbləğini Hesablamaq Nə Qədər Asandır (CRC32 - CRC16 - CRC8)

Video: CRC Nəzarət Məbləğini Hesablamaq Nə Qədər Asandır (CRC32 - CRC16 - CRC8)

Video: CRC Nəzarət Məbləğini Hesablamaq Nə Qədər Asandır (CRC32 - CRC16 - CRC8)
Video: How to calculate CRC (Cyclic Redundancy Check) 2024, Noyabr
Anonim

İnternetdə CRC hesablama məbləğini hesablamaq üçün bir çox seçim var. Bəs bir pul cəmi nədir və nə üçün bu şəkildə hesablanır? Gəlin anlayaq.

CRC hesablama məbləğini hesablamaq nə qədər asandır (CRC32 - CRC16 - CRC8)
CRC hesablama məbləğini hesablamaq nə qədər asandır (CRC32 - CRC16 - CRC8)

Təlimat

Addım 1

Əvvəlcə bir az nəzəriyyə əldə edək. Yaxşı CRC nədir? Bir sözlə, bu, cəmi hesablama növlərindən biridir. İdarəetmə məbləği, rabitə kanalları üzərindən ötürülmə zamanı qəbuledici tərəfdən alınan məlumatların bütövlüyünün yoxlanılması metodudur. Məsələn, ən sadə çeklərdən biri də paritet bitdən istifadə etməkdir. Bu, ötürülən mesajın bütün bitləri ümumiləşdirildikdə və cəmi cüt olduğu təqdirdə mesajın sonuna 0 əlavə olunur, əgər təkdirsə, onda 1 alınır. mesaj bitləri də sayılır və alınan paritet bitlə müqayisə olunur. Fərqlidirlərsə, ötürülmə zamanı səhvlər meydana gəldi və ötürülən məlumatlar təhrif edildi.

Ancaq səhvlərin mövcudluğunu aşkarlamaq üçün bu üsul çox məlumatlı deyil və həmişə işləmir, çünki mesajın bir neçə hissəsi təhrif olunarsa, cəmin pariteti dəyişə bilməz. Buna görə CRC də daxil olmaqla daha çox "inkişaf etmiş" çek var.

Əslində, CRC bir cəm deyil, müəyyən bir miqdarda məlumatın (məlumat mesajının) sabit ilə bölünməsinin nəticəsidir, daha doğrusu, bir mesajın sabit ilə bölünməsinin qalığıdır. Bununla birlikdə, CRC tarixən "nəzarət cəmi" olaraq da adlandırılır. Mesajın hər bir hissəsi CRC dəyərinə kömək edir. Yəni ötürülmə zamanı orijinal mesajın ən azı bir hissəsi dəyişərsə, nəzarət cəmi də dəyişəcək və əhəmiyyətli dərəcədə dəyişəcəkdir. Bu, belə bir çekin böyük bir artıdır, çünki orijinal mesajın ötürülmə zamanı təhrif olunub-olunmamasını birmənalı şəkildə müəyyənləşdirməyə imkan verir.

Addım 2

CRC-ni hesablamağa başlamazdan əvvəl bir az daha nəzəriyyəyə ehtiyac var.

Orijinal mesajın nə olduğu aydın olmalıdır. İxtiyari uzunluqlu bitlərin bitişik ardıcıllığıdır.

Orijinal mesajı bölməli olduğumuz sabit nədir? Bu rəqəm hər hansı bir uzunluqdadır, lakin ümumiyyətlə 1 baytdan çox istifadə olunur - 8, 16 və 32 bit. Sadəcə saymaq daha asandır, çünki kompüterlər bitlərlə deyil, baytlarla işləyir.

Bölücü sabiti ümumiyyətlə bu kimi polinom (polinom) kimi yazılır: x ^ 8 + x ^ 2 + x ^ 1 + x ^ 0. Burada "x" rəqəminin dərəcəsi, saydakı sıfırdan başlayan bir bitin mövqeyini bildirir və ən əhəmiyyətli bit çox polinomun dərəcəsini göstərir və ədədi şərh edərkən atılır. Yəni əvvəllər yazılmış rəqəm ikili olaraq (1) 00000111-dən və ya onluqdan 7-dən başqa bir şey deyildir. Mötərizədə nömrənin nəzərdə tutulan ən əhəmiyyətli rəqəmini göstərdim.

Budur başqa bir nümunə: x ^ 16 + x ^ 15 + x ^ 2 + x ^ 0 = (1) 1000000000000101 = 0x8005 = 32773.

Ümumiyyətlə bəzi standart polinomlar müxtəlif növ CRC-lər üçün istifadə olunur.

Addım 3

Bəs vergi cəmini necə hesablayırsınız? Hesablamaların sayını azaltmaq və müvafiq olaraq, CRC hesablamasını sürətləndirmək üçün bir mesajı bir polinom "baş üstə" bölmək və onun dəyişiklikləri əsas bir metoddur. Əsas metodu nəzərdən keçirəcəyik.

Ümumiyyətlə, bir ədədin çox polinuma bölünməsi aşağıdakı alqoritmə əsasən həyata keçirilir:

1) uzunluğu polinom genişliyinin uzunluğuna bərabər olan sıfırlarla doldurulmuş bir sıra (qeyd) yaradılır;

2) orijinal mesaj polinomun bit sayına bərabər miqdarda, ən az əhəmiyyətli bitlərdə sıfırlar ilə tamamlanır;

3) mesajın ən əhəmiyyətli biti reyestrin ən az əhəmiyyətli bitinə daxil edilir və bir bit qeydin ən əhəmiyyətli bitindən köçürülür;

4) genişləndirilmiş bit "1" -ə bərabərdirsə, bu çoxluqda olanlara uyğun gələn qeyd bitlərində bitlər ters çevrilir (XOR əməliyyatı, müstəsna VƏ);

5) mesajda hələ də bit varsa, addım 3);

6) mesajın bütün bitləri reyestrə daxil olduqda və bu alqoritmlə işləndikdə bölmənin qalan hissəsi CRC-nin nəzarət cəmi olan reyestrdə qalır.

Şəkil orijinal bit ardıcıllığının (1) 00000111 sayına və ya x ^ 8 + x ^ 2 + x ^ 1 + x ^ 0 polinomuna bölünməsini təsvir edir.

CRC hesablamasının şematik təsviri
CRC hesablamasının şematik təsviri

Addım 4

Bir neçə əlavə toxunuş qalıb. Gördüyünüz kimi, mesaj istənilən saya bölünə bilər. Bunu necə seçmək olar? CRC-ni hesablamaq üçün istifadə olunan bir sıra standart polinomlar var. Məsələn, CRC32 üçün 0x04C11DB7, CRC16 üçün 0x8005 ola bilər.

Bundan əlavə, hesablamanın başlanğıcındakı qeyddə sıfır deyil, başqa bir sıra yaza bilərsiniz.

Ayrıca, hesablamalar zamanı, son CRC pul cəmini vermədən dərhal əvvəl, onları başqa bir ədədə bölmək olar.

Və son şey. Qeydiyyata yazarkən mesajın baytları ən önəmli bit "irəli", əksinə ən az əhəmiyyətli olaraq yerləşdirilə bilər.

Addım 5

Yuxarıda göstərilənlərin hamısına əsasən, yuxarıda təsvir etdiyim bir sıra parametrləri götürərək CRC dəyərini 32 bit imzasız bir rəqəm kimi qaytarmaqla CRC nəzarət məbləğini hesablayan Basic. NET funksiyası yazaq.

İctimai Paylaşılan Fonksiyon GetCrc (ByVal bayt As Byte (), ByVal poly As UInteger, Könüllü ByVal eni Integer = 32, İsteğe bağlı ByVal initReg As UInteger = & HFFFFFFFFUI, Könüllü ByVal finalXor As UInteger OptyFoFFtion, & reverseCrc As Boolean = True) UInteger kimi

Dim widthInBytes As Integer = width / 8

'Mesaj genişliyini sıfırlar ilə əlavə edin (baytlarla hesablama):

ReDim Qoruyan baytlar (bayt. Uzunluq - 1 + widthInBytes)

'Mesajdan bir az növbə yaradın:

Dim msgFifo Yeni Sıra Olaraq (Boolean) (bayt. Sayı * 8 - 1)

Bayt olaraq hər b üçün

Dim ba kimi Yeni BitArray ({b})

Əgər reverseBytes Sonra

I for Integer = 0 - 7

msgFifo. Enqueue (ba (i))

Növbəti

Başqa

Üçün I Tamsayı = 7-dən 0-a qədər addım -1

msgFifo. Enqueue (ba (i))

Növbəti

Bitirsə

Növbəti

Qeydlərin ilkin doldurulma bitlərindən bir növbə yaradın:

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

Dim initBytesReversed IEnumerable (Of Byte) = (B As Byte InitBytes widthInBytes götürün). Reverse

Dim initFifo Yeni Növbə Olaraq (Boolean) (eni - 1)

Bayt olaraq hər b üçün initBytesReversed

Dim ba kimi Yeni BitArray ({b})

Sonra reverseBytes deyilsə

I for Integer = 0 - 7

initFifo. Enqueue (ba (i))

Növbəti

Başqa

Üçün I Tamsayı = 7-dən 0-a qədər addım -1

initFifo. Enqueue (ba (i))

Növbəti

Bitirsə

Növbəti

'Shift və XOR:

Dim registr UInteger = 0 'olaraq, en-bit qeydini sıfırlarla doldurun.

Do while msgFifo. Count> 0

Dim poppedBit As Integer = CInt (qeyd >> (eni - 1)) və 1 'növbə qeydindən əvvəl müəyyənləşdirin.

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

İnitFifo. Count> 0 olduqda

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

shifttedBit = shifttedBit Xor b

Bitirsə

qeyd = qeyd << 1

qeydiyyatdan = qeyddən və ya shiftledBit

PoppedBit = 1 Sonra

qeyd = qeyd Xor poly

Bitirsə

Döngü

'Son dönüşümlər:

Dim crc As UInteger = register 'Qeyd bölmənin qalan hissəsini ehtiva edir == cəmi.

Əgər reverseCrc Sonra

crc = əks etdir (crc, en)

Bitirsə

crc = crc Xor finalXor

crc = crc Və (& HFFFFFFFFUI >> (32 - eni)) 'ən az əhəmiyyətli bitləri maskalamaq.

Qayıt crc

Son İşləmə

Tövsiyə: