Mungkin saya hanya tidak melihatnya, tetapi CRC32 tampaknya rumit, atau tidak cukup dijelaskan di mana pun yang dapat saya temukan di web.
Saya mengerti bahwa itu adalah sisa dari pembagian aritmatika berbasis non-carry dari nilai pesan, dibagi dengan polinomial (generator), tetapi implementasi sebenarnya dari itu luput dari saya.
Saya telah membaca A Painless Guide To CRC Error Detection Algorithms , dan saya harus mengatakan itu bukan tanpa rasa sakit. Ini membahas teori dengan cukup baik, tetapi penulis tidak pernah sampai pada pertanyaan sederhana "ini dia." Dia memang mengatakan apa parameter untuk algoritma CRC32 standar, tetapi dia lalai menjelaskan dengan jelas bagaimana Anda mendapatkannya.
Bagian yang membuat saya tertarik adalah ketika dia mengatakan "ini dia" dan kemudian menambahkan, "oh ngomong-ngomong, ini bisa dibalik atau dimulai dengan kondisi awal yang berbeda," dan tidak memberikan jawaban yang jelas tentang cara akhirnya menghitung checksum CRC32 mengingat semua perubahan yang baru saja dia tambahkan.
- Apakah ada penjelasan yang lebih sederhana tentang bagaimana CRC32 dihitung?
Saya mencoba membuat kode dalam C bagaimana tabel terbentuk:
for (i = 0; i < 256; i++)
{
temp = i;
for (j = 0; j < 8; j++)
{
if (temp & 1)
{
temp >>= 1;
temp ^= 0xEDB88320;
}
else {temp >>= 1;}
}
testcrc[i] = temp;
}
tetapi ini tampaknya menghasilkan nilai yang tidak sesuai dengan nilai yang saya temukan di tempat lain di Internet. Saya dapat menggunakan nilai yang saya temukan online, tetapi saya ingin memahami bagaimana nilai itu dibuat.
Bantuan apa pun untuk menyelesaikan angka-angka yang sangat membingungkan ini akan sangat kami hargai.
0xEDB88320
juga dapat ditulis msbit-first ( normal ) sebagai0x04C11DB7
. Apakah nilai tabel yang Anda temukan di tempat lain dibuat menggunakan polinomial CRC yang sama?Jawaban:
Polinomial untuk CRC32 adalah:
Atau dalam hex dan biner:
Istilah tertinggi (x 32 ) biasanya tidak ditulis secara eksplisit, sehingga dapat direpresentasikan dalam hex seperti
Jangan ragu untuk menghitung 1 dan 0, tetapi Anda akan menemukannya cocok dengan polinomial, di mana
1
bit 0 (atau bit pertama) danx
bit 1 (atau bit kedua).Mengapa polinomial ini? Karena perlu ada polinomial standar yang diberikan dan standar itu ditetapkan oleh IEEE 802.3. Juga sangat sulit untuk menemukan polinomial yang mendeteksi kesalahan bit berbeda secara efektif.
Anda dapat menganggap CRC-32 sebagai rangkaian "Aritmatika Biner tanpa Pengangkutan", atau pada dasarnya "operasi XOR dan shift". Ini secara teknis disebut Aritmatika Polinomial.
Untuk lebih memahaminya, pikirkan perkalian ini:
Jika kita mengasumsikan x adalah basis 2 maka kita mendapatkan:
Mengapa? Karena 3x ^ 3 adalah 11x ^ 11 (tapi kita hanya membutuhkan 1 atau 0 digit awal) jadi kita bawa:
Tetapi ahli matematika mengubah aturan tersebut sehingga menjadi mod 2. Jadi pada dasarnya semua polinomial biner mod 2 hanyalah penjumlahan tanpa membawa atau XOR. Jadi persamaan asli kita terlihat seperti ini:
Saya tahu ini adalah lompatan keyakinan tetapi ini di luar kemampuan saya sebagai programmer garis. Jika Anda adalah siswa atau insinyur CS inti, saya menantang untuk memecahnya. Semua orang akan mendapat manfaat dari analisis ini.
Jadi untuk mengerjakan contoh lengkap:
Sekarang kita membagi Pesan yang ditambah dengan Poly menggunakan aritmatika CRC. Ini adalah divisi yang sama seperti sebelumnya:
Pembagian menghasilkan hasil bagi, yang kita buang, dan sisanya, yang merupakan checksum yang dihitung. Ini mengakhiri perhitungan. Biasanya, checksum kemudian ditambahkan ke pesan dan hasilnya dikirim. Dalam hal ini transmisi akan menjadi: 11010110111110.
Gunakan hanya angka 32-bit sebagai pembagi Anda dan gunakan seluruh aliran Anda sebagai dividen. Buang hasil bagi dan simpan sisanya. Tack sisanya di akhir pesan Anda dan Anda memiliki CRC32.
Ulasan pria rata-rata:
(Perhatikan bahwa aliran harus dapat dibagi dengan 32 bit atau harus diisi. Misalnya, aliran ANSI 8-bit harus di-padded. Juga di akhir aliran, pembagian dihentikan.)
sumber
x^6 + x^5 + x^4 + 3*x^3 + x^2 + x^1 + x^0 ... If we assume x is base 2 then we get: x^7 + x^3 + x^2 + x^1 + x^0
. Ini bukan cara kerja matematika. Koefisien untuk polinomial adalah mod (2) atau GF (2), x dibiarkan saja, menghasilkan x ^ 6 + x ^ 5 + x ^ 4 + x ^ 3 + x ^ 2 + x ^ 1 + x ^ 0 (karena 3 mod (2) = 1).Tack the remainder on the end of your message
- secara teknis sisa dikurangi dari 0 bit yang ditambahkan ke pesan, tetapi karena ini adalah mod (2) matematika, baik menambah dan mengurangi sama dengan XOR, dan nol bit XOR'ed dengan sisanya sama sebagai sisanya.Why did you append four 0s though?
- algoritma perangkat lunak untuk menghitung crc secara efektif menambahkan 0s, meskipun tidak terlihat. Jika menampilkan penghitungan CRC menggunakan pembagian tangan panjang, maka 0 perlu ditambahkan agar contoh pembagian muncul dengan benar.Untuk IEEE802.3, CRC-32. Pikirkan seluruh pesan sebagai aliran bit serial, tambahkan 32 angka nol di akhir pesan. Selanjutnya, Anda HARUS membalik bit SETIAP byte pesan dan melakukan 1 untuk melengkapi 32 bit pertama. Sekarang bagi dengan polinomial CRC-32, 0x104C11DB7. Akhirnya, Anda harus 1 melengkapi sisa 32-bit dari pembagian ini bit-reverse masing-masing dari 4 byte sisanya. Ini menjadi CRC 32-bit yang ditambahkan ke akhir pesan.
Alasan untuk prosedur aneh ini adalah bahwa implementasi Ethernet pertama akan membuat pesan menjadi serial satu byte pada satu waktu dan mengirimkan bit paling signifikan dari setiap byte terlebih dahulu. Aliran bit serial kemudian melewati komputasi register geser CRC-32 serial, yang hanya dilengkapi dan dikirim melalui kabel setelah pesan selesai. Alasan untuk melengkapi 32 bit pertama dari pesan tersebut adalah agar Anda tidak mendapatkan CRC nol semua meskipun pesan tersebut semuanya nol.
sumber
CRC sangat sederhana; Anda mengambil polinomial yang direpresentasikan sebagai bit dan data, dan membagi polinomial tersebut menjadi data (atau Anda merepresentasikan data sebagai polinomial dan melakukan hal yang sama). Sisanya, antara 0 dan polinomial adalah CRC. Kode Anda agak sulit dipahami, sebagian karena tidak lengkap: temp dan testcrc tidak dideklarasikan, jadi tidak jelas apa yang diindeks, dan berapa banyak data yang berjalan melalui algoritme.
Cara untuk memahami CRC adalah dengan mencoba menghitung beberapa menggunakan potongan data pendek (16 bit atau lebih) dengan polinomial pendek - 4 bit, mungkin. Jika Anda berlatih dengan cara ini, Anda akan benar-benar memahami bagaimana Anda bisa melakukan pengkodeannya.
Jika Anda sering melakukannya, CRC cukup lambat untuk dihitung dalam perangkat lunak. Komputasi perangkat keras jauh lebih efisien, dan hanya membutuhkan beberapa gerbang.
sumber
Selain pemeriksaan redundansi Siklik Wikipedia dan artikel Perhitungan CRC , saya menemukan sebuah makalah berjudul Reversing CRC - Theory and Practice * untuk menjadi referensi yang baik.
Pada dasarnya ada tiga pendekatan untuk menghitung CRC: pendekatan aljabar, pendekatan berorientasi bit, dan pendekatan berbasis tabel. Dalam Reversing CRC - Theory and Practice * , masing-masing dari tiga algoritma / pendekatan ini dijelaskan dalam teori disertai dalam LAMPIRAN dengan implementasi untuk CRC32 dalam bahasa pemrograman C.
* PDF Link
CRC Pembalik - Teori dan Praktek.
Laporan Publik HU Berlin
SAR-PR-2006-05
Mei 2006
Penulis:
Martin Stigge, Henryk Plötz, Wolf Müller, Jens-Peter Redlich
sumber
Saya menghabiskan waktu untuk mencoba mengungkap jawaban atas pertanyaan ini, dan akhirnya saya menerbitkan tutorial tentang CRC-32 hari ini: tutorial hash CRC-32 - Komunitas AutoHotkey
Dalam contoh ini, saya menunjukkan cara menghitung hash CRC-32 untuk string ASCII 'abc':
sumber
^
? stackoverflow.com/questions/62168128/…Lalu selalu ada Rosetta Code, yang menunjukkan crc32 diimplementasikan dalam banyak bahasa komputer. https://rosettacode.org/wiki/CRC-32 dan memiliki tautan ke banyak penjelasan dan implementasi.
sumber
Untuk mengurangi crc32 untuk menerima pengingat, Anda perlu:
Dalam kode ini adalah:
di mana reminderIEEE adalah pengingat murni di GF (2) [x]
sumber