Skip to content
Kembali ke Blog
Tutorial

Varian CRC-16: Mengapa MODBUS, CCITT, dan XMODEM Berbeda

Byte yang sama, empat hasil CRC-16 berbeda. Pelajari online bagaimana poly, init, refin, refout, dan xorout memisahkan MODBUS dari CCITT-FALSE dan XMODEM.

13 menit baca

Mengapa Byte yang Sama Menghasilkan Empat Nilai CRC-16 Berbeda

CRC-16 itu nama sebuah keluarga, bukan nama satu algoritma tertentu, dan anggotanya saling bertentangan. Kirim byte yang sama ke MODBUS, lalu ke CCITT-FALSE, lalu ke XMODEM: Anda akan dapat tiga bilangan 16-bit yang sama sekali tidak mirip satu sama lain.

Yang menentukan anggota mana yang sedang Anda jalankan ada lima konstanta: poly, init, refin, refout, dan xorout. Ubah satu saja dan keluarannya berubah total; tidak ada kemiripan sebagian yang bisa memperingatkan Anda bahwa ada yang meleset. Kebanyakan pertanyaan “kenapa CRC saya tidak cocok dengan perangkatnya” berhenti tepat di titik itu: kedua sisi menjalankan varian berbeda, dan tidak ada yang pernah mencatat varian mana.

Semua nilai dalam panduan ini kami hitung dengan model CRC terparameter di Python 3.14.7 pada macOS, lalu kami periksa silang dengan empat cara: terhadap zlib.crc32 dan binascii.crc_hqx dari pustaka standar, terhadap nilai check yang tercantum di katalog CRC RevEng, dan terhadap dokumentasi vendor untuk masing-masing set parameter.

1. Frame yang sama, empat hasil CRC-16

Ini sebuah permintaan Modbus RTU sungguhan. Slave 01, kode fungsi 03 (read holding registers), alamat awal 0x0000, kuantitas 0x000A:

01 03 00 00 00 0A

Enam byte yang sama melewati empat varian:

VarianHasilDi jalur transmisi (byte rendah dulu)
CRC-16/MODBUS0xCDC5C5 CD
CRC-16/IBM-3740 (CCITT-FALSE)0x042828 04
CRC-16/XMODEM0x0A3838 0A
CRC-16/ARC0xD6C5C5 D6

Keempat nilai itu sama sekali tidak berhubungan. Pola nibble-nya berlainan, selisih antar-nilainya bukan konstanta, dan tidak ada trik pengurutan yang mengubah satu menjadi yang lain. Dua di antaranya memang diawali byte yang sama di jalur transmisi, dan itu murni kebetulan.

Jadi tulisan “CRC-16” pada sebuah datasheet hampir tidak berisi informasi. Yang Anda tahu dari situ cuma lebar keluarannya, 16 bit. Kalau Anda ingin melihat hasilnya dalam radiks lain sambil membandingkannya dengan perangkat yang mencetak biner, konverter basis bilangan membalik nilai 16-bit antara heksadesimal dan biner tanpa perlu memikirkan padding.

2. Apa yang diubah masing-masing dari kelima parameter

Di balik setiap varian ada mesin yang sama: sebuah shift register yang melahap satu bit setiap kali, dan meng-XOR-kan sebuah konstanta setiap kali angka 1 jatuh dari puncak. Parameternya menentukan apa yang masuk ke register dan ke arah mana bit-bit itu bergerak, ditambah satu XOR terakhir di jalan keluar.

Seluruh mesinnya muat dalam empat belas baris Python. Implementasinya bit-per-bit, lambat tetapi mudah dibaca, dan ia menghasilkan ulang setiap nilai di artikel ini:

def crc(data, width, poly, init, refin, refout, xorout):
    top = 1 << (width - 1)
    mask = (1 << width) - 1
    reg = init
    for byte in data:
        if refin:
            byte = int(f"{byte:08b}"[::-1], 2)
        reg ^= byte << (width - 8)
        for _ in range(8):
            reg = ((reg << 1) ^ poly) if reg & top else (reg << 1)
            reg &= mask
    if refout:
        reg = int(f"{reg:0{width}b}"[::-1], 2)
    return reg ^ xorout

Pustaka standar Python bisa memeriksa silang keluaran mesin ini. zlib.crc32 dan binascii.crc_hqx masing-masing memberi jawaban independen, dan ketiganya cocok:

zlib.crc32(b"123456789")               = 0xCBF43926   engine above = 0xCBF43926   MATCH
binascii.crc_hqx(b"123456789", 0x0000) = 0x31C3       CRC-16/XMODEM = 0x31C3      MATCH
binascii.crc_hqx(b"123456789", 0xFFFF) = 0x29B1       CCITT-FALSE   = 0x29B1      MATCH

poly: dua kubu, 0x8005 dan 0x1021

Polinomial adalah konstanta yang di-XOR-kan kembali ke dalam register. Ia ditulis dalam bentuk “normal”, dengan bit teratas tersirat, sehingga 0x8005 berarti x^16 + x^15 + x^2 + 1 dan 0x1021 berarti x^16 + x^12 + x^5 + 1. Loop geser-dan-XOR itu sama saja dengan pembagian panjang polinomial di atas GF(2): polinomialnya adalah pembagi, register menyimpan sisa bagi yang sedang berjalan, dan setiap bit pesan memajukan pembagian itu satu langkah.

Hampir setiap CRC-16 yang Anda temui memakai salah satu dari keduanya. 0x8005 mencakup ARC, MODBUS, dan USB. Di bawah 0x1021 berkumpul seluruh kekusutan CCITT ditambah XMODEM, KERMIT, dan varian-varian RFID. Jadi polinomialnya saja tidak pernah cukup untuk mengenali sebuah varian.

init: nilai awal register

Dua nilai mendominasi: 0x0000 dan 0xFFFF, dan pilihan di antara keduanya lebih berarti daripada kelihatannya. Mulai dari nol, maka sebuah byte nol meninggalkan register tetap di nol, sehingga 00 00 01 dan 01 menghasilkan CRC yang identik. Pesan yang bertambah atau kehilangan nol di depan saat transit tetap lolos pemeriksaan. Memulai dari 0xFFFF menghilangkan titik buta itu, dan itulah alasan Modbus, CCITT-FALSE, dan USB sama-sama memakainya.

refin dan refout: urutan bit, bukan urutan byte

refin membalik delapan bit setiap byte masukan sebelum byte itu masuk ke register. refout membalik isi akhir register sebelum XOR terakhir. Perangkat keras yang menggeser data keluar secara LSB-first mendapatkan pembalikan ini secara cuma-cuma, jadi varian yang direfleksikan cenderung berasal dari protokol serial.

Orang paling sering mengacaukan pasangan parameter ini dengan endianness. Keduanya bekerja pada tingkat yang berbeda, dan bagian 6 mengurai perbedaannya.

xorout: XOR terakhir

Ini langkah terakhir: satu XOR yang mengenai register setelah refout selesai. Untuk CRC-16 nilainya biasanya 0x0000 atau 0xFFFF; keluarga CRC-32 memakai 0xFFFFFFFF. Parameter inilah yang paling gampang salah dipasang tanpa Anda sadari, karena ketidakcocokan di sini terlihat persis sama dengan ketidakcocokan di titik mana pun.

width: 8, 16, atau 32 bit

Lebar menentukan batas atas kemampuan deteksi. CRC selebar n menangkap setiap burst error sepanjang maksimal n bit, dan meleset pada kerusakan acak dengan peluang sekitar 2^-n. Itu berarti 1 banding 65.536 untuk CRC-16 dan 1 banding 4,3 miliar untuk CRC-32.

Kalau kita berangkat dari CRC-16/XMODEM dan mengubah tepat satu parameter setiap kali, dengan masukan uji standar 123456789:

baseline CRC-16/XMODEM                        = 0x31C3
init 0x0000 -> 0xFFFF   (becomes CCITT-FALSE) = 0x29B1
refin/refout -> true    (becomes KERMIT)      = 0x2189
xorout 0x0000 -> 0xFFFF                       = 0xCE3C
poly 0x1021 -> 0x8005                         = 0xFEE8

Membalik satu flag saja sudah memberi keluaran yang sama sekali lain. Dalam CRC tidak ada istilah “hampir cocok”: dua hasil itu cocok, atau ketidakcocokannya sama sekali tidak memberi tahu Anda seberapa jauh masukannya meleset, sehingga menatap sebuah ketidakcocokan tidak akan pernah melokalisasi penyebabnya. Loop terdalamnya cuma XOR dan pergeseran; panduan lengkap operasi bitwise membahas operatornya satu per satu kalau bagian itu masih terasa asing.

3. “CCITT” adalah nama yang buruk

Per September 2026, katalog CRC RevEng mendaftar 31 definisi CRC 16-bit yang berbeda, dan tiga di antaranya memakai label CCITT. Ketiganya tidak sepakat satu sama lain. Empat baris di bawah ini berbagi polinomial dan masukan yang sama, lalu mendarat pada empat hasil yang tidak berhubungan:

Nama umumNama katalogcheckinitrefin/refoutxorout
CCITT-FALSECRC-16/IBM-37400x29B10xFFFFfalse0x0000
XMODEMCRC-16/XMODEM0x31C30x0000false0x0000
CCITT “yang asli”CRC-16/KERMIT0x21890x0000true0x0000
CRC-16/MCRF4XX0x6F910xFFFFtrue0x0000

Riwayat penamaannya sendiri tidak banyak menolong. Katalog mendaftar CRC-16/KERMIT dengan alias CRC-CCITT dan CRC-16/CCITT-TRUE, dan varian itulah yang direfleksikan. Sebuah implementasi tanpa refleksi dengan init 0xFFFF juga beredar luas dengan nama CCITT, dan itulah sebabnya katalog mencatat “CCITT-FALSE” sebagai alias dari CRC-16/IBM-3740. XMODEM duduk di antara keduanya: polinomial sama, tanpa refleksi, init nol.

Jadi ketika sebuah datasheet menyebut CCITT, yang Anda dapat cuma satu keterangan: polinomialnya 0x1021. Empat kandidat masih tersisa, dan kalau Anda salah pilih, nilai yang keluar tampak sama masuk akalnya dengan nilai yang benar.

Karena itu, cantumkan parameternya di dokumen protokol Anda, bukan sekadar namanya. Satu baris poly=0x1021, init=0xFFFF, refin=false, refout=false, xorout=0x0000 sudah menutup persoalan ini untuk seterusnya, sementara “CRC-16/CCITT” meninggalkan tebakan yang sama seperti sebelumnya.

4. Cara mengenali varian CRC-16 mana yang Anda pakai

Katalog menyelesaikan ini dengan sebuah sidik jari. Setiap entri memublikasikan nilai check: CRC dari sembilan byte ASCII 123456789. Jalankan string itu melalui implementasi yang ada di depan Anda, lalu cari hasilnya di tabel.

Variancheckpolyinitrefinrefoutxorout
CRC-16/ARC (IBM/LHA)0xBB3D0x80050x0000truetrue0x0000
CRC-16/MODBUS0x4B370x80050xFFFFtruetrue0x0000
CRC-16/USB0xB4C80x80050xFFFFtruetrue0xFFFF
CRC-16/IBM-3740 (CCITT-FALSE)0x29B10x10210xFFFFfalsefalse0x0000
CRC-16/XMODEM0x31C30x10210x0000falsefalse0x0000
CRC-16/KERMIT (CCITT yang asli)0x21890x10210x0000truetrue0x0000
CRC-16/GENIBUS0xD64E0x10210xFFFFfalsefalse0xFFFF
CRC-16/MCRF4XX0x6F910x10210xFFFFtruetrue0x0000
CRC-32/ISO-HDLC (zip, PNG, zlib)0xCBF439260x04C11DB70xFFFFFFFFtruetrue0xFFFFFFFF
CRC-32/BZIP20xFC8919180x04C11DB70xFFFFFFFFfalsefalse0xFFFFFFFF
CRC-32C (Castagnoli, iSCSI)0xE30692830x1EDC6F410xFFFFFFFFtruetrue0xFFFFFFFF
CRC-8/SMBUS0xF40x070x00falsefalse0x00
CRC-8/MAXIM-DOW (1-Wire)0xA10x310x00truetrue0x00

Ada satu detail yang menggagalkan banyak perbandingan: 123456789 berarti sembilan byte 31 32 33 34 35 36 37 38 39, bukan bilangan 123456789 dan bukan pula string berakhiran null. Jika bahasa Anda menyerahkan wide string ke fungsi itu atau menambahkan terminator, Anda sedang menghitung hash atas masukan yang berbeda dan setiap baris akan meleset. Payload non-ASCII menambah jebakan kedua: teks yang sama, dikodekan sebagai UTF-8 dan sebagai Windows-1252, adalah dua urutan byte yang berbeda, dan karenanya dua CRC yang berbeda. Tabel dan konverter ASCII menampilkan byte di balik setiap karakter, sehingga Anda bisa memastikan byte mana yang sebenarnya masuk.

Kalau nilai check tidak cocok dengan satu baris pun, singkirkan dulu penyebab yang membosankan sebelum mencurigai adanya polinomial khusus:

  1. Urutan byte-nya terbalik, karena Anda membaca hasilnya langsung dari jalur transmisi.
  2. Cakupan field-nya berbeda: pengirim ikut menghitung, atau justru melewati, byte alamat, byte panjang, atau field CRC itu sendiri.
  3. Vendornya memakai init sendiri yang bukan 0x0000 maupun 0xFFFF. Ini betul-betul terjadi pada protokol meteran proprietary, dan keterangannya biasanya terkubur di catatan kaki.

Membongkar parameter dengan brute force

Kalau vendor tidak mau memberi tahu dan Anda tidak bisa membaca firmware mereka, mintalah satu hal saja: sebuah frame hasil tangkapan beserta CRC yang dihasilkan perangkat mereka untuk frame itu. Lalu lakukan enumerasi. Dua polinomial, dua nilai init, refin dan refout yang bisa hidup-mati sendiri-sendiri, serta dua nilai xorout: totalnya 32 kombinasi, dan segitu bisa Anda sapu habis sekaligus:

target = 0x4B37                    # nilai yang dikembalikan implementasi mereka
for poly in (0x8005, 0x1021):
    for init in (0x0000, 0xFFFF):
        for refin in (False, True):
            for refout in (False, True):
                for xorout in (0x0000, 0xFFFF):
                    if crc(b"123456789", 16, poly, init, refin, refout, xorout) == target:
                        print(f"poly=0x{poly:04X} init=0x{init:04X} "
                              f"refin={refin} refout={refout} xorout=0x{xorout:04X}")
poly=0x8005 init=0xFFFF refin=True refout=True xorout=0x0000

Satu kecocokan, dan itu CRC-16/MODBUS. Ganti 123456789 dengan frame sungguhan, dan sapuan 32 kombinasi yang sama bekerja pada pesan apa pun yang CRC benarnya sudah Anda ketahui. Jika beberapa kombinasi bertahan pada satu sampel, jalankan frame kedua lalu iriskan hasilnya.

5. Modbus RTU dalam praktik

Modbus RTU memakai CRC-16/MODBUS: polinomial 0x8005, init 0xFFFF, direfleksikan di masukan dan keluaran, tanpa XOR akhir. Untuk permintaan enam byte kita tadi, CRC-nya adalah 0xCDC5, dan frame yang sudah lengkap menjadi:

01 03 00 00 00 0A C5 CD

Urutan di jalur transmisi adalah kebalikan dari cara Anda menuliskan nilainya

Nilainya 0xCDC5, tetapi byte yang masuk ke frame adalah C5 CD. Modbus menetapkan byte rendah CRC lebih dulu, yang merupakan kebalikan dari urutan saat Anda membaca bilangan heksadesimalnya, dan hal ini terus-menerus menjebak orang. Setiap field multi-byte lain dalam frame yang sama, termasuk jumlah register 00 0A itu, bersifat big-endian. CRC-lah pengecualiannya.

Ini punya efek samping yang berguna. Hitung CRC-16/MODBUS atas seluruh frame, termasuk byte CRC-nya, dan hasilnya adalah:

0x0000

Itulah keseluruhan rutin validasi di sisi penerima. Penerima tidak perlu memisahkan dua byte terakhir, menukar urutannya, lalu membandingkannya dengan nilai yang dihitung secara lokal. Jalankan CRC atas semua yang tiba dan periksa apakah hasilnya nol. Dengan begitu tidak tersisa satu pun langkah pembalikan byte yang bisa Anda kacaukan.

Mengapa dokumentasi Modbus menampilkan 0xA001

Buka hampir semua implementasi Modbus dan konstanta di kode sumbernya adalah 0xA001, bukan 0x8005. Keduanya benar. 0xA001 adalah 0x8005 dengan 16 bitnya dibalik, dan ia milik bentuk algoritma yang direfleksikan, di mana register bergeser ke kanan alih-alih ke kiri dan byte masukan tidak perlu dibalik satu per satu. Kedua implementasi menghasilkan keluaran yang identik; hanya bagian dalamnya yang berbeda. Kalau Anda melihat 0xA001 di kode sumber, itu penanda yang andal bahwa implementasinya bentuk refleksi.

Satu hal lagi yang perlu Anda waspadai saat membaca hasil tangkapan: Modbus ASCII adalah framing terpisah yang membawa setiap byte sebagai dua karakter heksadesimal di antara 3A (:) di depan dan 0D 0A di belakang, dan ia memakai LRC, bukan CRC. Kalau trace Anda menunjukkan 3A 30 31 30 33 di tempat Anda mengharapkan 01 03, Anda sedang berada di mode ASCII dan tidak ada varian CRC yang akan pernah cocok. Tabel ASCII memetakan byte-byte itu langsung kembali menjadi karakter.

Algoritma yang sama dalam C

Firmware Modbus hampir tidak pernah memakai model Python di atas. Ia memakai bentuk refleksi secara langsung, menggeser ke kanan dan meng-XOR dengan 0xA001:

uint16_t crc16_modbus(const uint8_t *buf, size_t len) {
    uint16_t crc = 0xFFFF;
    for (size_t i = 0; i < len; i++) {
        crc ^= buf[i];
        for (int b = 0; b < 8; b++)
            crc = (crc & 1) ? (crc >> 1) ^ 0xA001 : crc >> 1;
    }
    return crc;
}

Untuk frame 01 03 00 00 00 0A, fungsi ini mengembalikan 0xCDC5, nilai yang sama dengan yang dihasilkan mesin Python tadi. String uji 123456789 memberi 0x4B37. Keduanya kami jalankan di bawah Apple clang 21 dan cocok bit demi bit dengan tabel di bagian 4.

6. refin/refout bukan endianness

Kekeliruan ini mahal harganya karena sebuah frame Modbus memuat keduanya sekaligus. Endianness berbicara tentang byte di dalam sebuah nilai multi-byte: apakah 0xCDC5 disimpan atau dikirim sebagai CD C5 atau C5 CD. Tidak ada yang bergerak di dalam sebuah byte. Itulah tingkatan yang dibahas tuntas oleh big-endian versus little-endian.

Refleksi berbicara tentang bit di dalam satu byte. refin membalik delapan bit setiap byte sebelum register melihatnya: bit 0 menjadi bit 7. Byte itu tetap di posisinya dalam pesan. Kedua pengaturan itu tidak saling memengaruhi.

Dalam sebuah frame Modbus, keduanya terjadi sekaligus dan saling independen:

  • Di dalam algoritma, refin dan refout bernilai true, sehingga algoritma membalik bit di dalam byte.
  • Di jalur transmisi, pengirim menempelkan CRC yang sudah jadi dengan byte rendah lebih dulu, dan itu keputusan urutan byte di tingkat protokol.

Mematikan refleksi untuk “memperbaiki” masalah urutan byte justru menghasilkan varian yang sama sekali lain, dan menukar byte terakhir frame untuk mengompensasi ketidakcocokan refleksi cuma memberi Anda nilai salah lewat jalan yang baru. Diagnosis satu per satu: benarkan dulu nilai check dengan algoritmanya saja, baru urus tata letak frame-nya.

7. CRC-32 vs CRC-16: mana yang sebaiknya Anda pakai?

CRC-32 punya masalah yang sama dengan CRC-16, hanya saja kurang kelihatan, karena satu varian mendominasi begitu total sampai kebanyakan pengembang tidak pernah tahu ada varian lain.

Variancheckpolyrefin/refout
CRC-32/ISO-HDLC0xCBF439260x04C11DB7true
CRC-32/BZIP20xFC8919180x04C11DB7false
CRC-32C (Castagnoli)0xE30692830x1EDC6F41true

ISO-HDLC adalah varian yang dihitung zlib.crc32. Zip menyimpannya per entri di central directory, dan setiap chunk PNG diakhiri dengan satu nilai yang mencakup tipe chunk beserta datanya. Frame check sequence pada Ethernet memakai set parameter yang sama di akhir setiap frame yang dikirim server Anda. BZIP2 adalah polinomial itu dengan refleksi dimatikan, yang menghasilkan nilai yang tidak punya kesamaan apa pun dengan ISO-HDLC.

CRC-16 juga muncul di lingkungan yang sama: Redis Cluster mengarahkan sebuah key ke salah satu dari 16.384 slot-nya dengan CRC16(key) mod 16384, dan itulah sebabnya key dengan hash tag yang sama mendarat di node yang sama.

Mengapa CRC-32C mendapat dukungan perangkat keras

CRC-32C memakai polinomial berbeda dengan deteksi kesalahan yang lebih baik pada blok-blok pendek yang biasa dikirim protokol penyimpanan dan jaringan. Karena itu iSCSI, checksum metadata ext4, SCTP, dan Btrfs memilihnya. Lalu Intel menanamkannya ke silikon: instruksi crc32 pada SSE4.2 menghitung CRC-32C secara langsung, sehingga pemeriksaan integritas jadi nyaris gratis di x86 modern. Kalau Anda memilih CRC untuk kode baru dan tidak terikat kompatibilitas dengan apa pun, ambil yang ini.

Tidak satu pun di antaranya cocok dipakai untuk memverifikasi sebuah unduhan. Ketika Anda menginginkan checksum untuk memastikan sebuah berkas tiba utuh, generator hash MD5 adalah alat yang akrab, dan MD5 vs SHA-256 membahas digest mana yang layak dipercaya untuk keperluan apa. CRC menjawab “apakah ini rusak di jalan”; hash kriptografis menjawab “apakah ini persis isi yang saya harapkan”.

8. CRC tidak menghentikan pemalsuan

Dua pesan JSON berikut punya makna yang berlawanan dan CRC-32 yang sama:

message A = b'{"to":"alice","amount":100}  H\xf6\xc0E'
message B = b'{"to":"mallory","amount":999}\xb2\xb2\xc2\xc2'
CRC-32(A) = 0x12345678
CRC-32(B) = 0x12345678

SHA-256 atas kedua pesan yang sama:

A -> a83b90f5e3f21dd32039e0e693a8b15864eda83e258c115deeee50a60c09ae23
B -> f9319ee0507d719c7260535dff33df721ddd9c0e1857690f3d8e02f92601b742

Tidak ada brute force di sini: byte di ekornya kami pecahkan secara aljabar. CRC adalah fungsi linear, dan menambahkan empat byte ke sebuah pesan memetakan ke keluaran CRC-32 sebagai sebuah bijeksi, sehingga untuk pesan apa pun dan nilai target apa pun ada tepat satu sufiks empat byte yang membawa Anda ke sana, dan menemukannya sekadar soal aritmetika.

Menambahkan empat byte hasil pemecahan 46 C9 6E 0B ke hello world:

CRC-32(b'hello world' + 46 C9 6E 0B) = 0xDEADBEEF   target 0xDEADBEEF   MATCH

Karena itu, penyerang yang bisa memodifikasi payload Anda juga bisa membetulkan CRC Anda, dalam waktu konstan, tanpa perlu mencari apa pun. Menaruh sebuah rahasia di depan pesan tidak menyelamatkannya: untuk suntingan yang mempertahankan panjang pesan, koreksi yang diterapkan pada CRC hanya bergantung pada bit-bit yang berubah, jadi penyerang bisa menghitungnya tanpa pernah tahu rahasianya. Itulah bentuk serangan yang meruntuhkan WEP.

CRC dirancang untuk menghadapi derau transmisi, yang sifatnya acak dan tidak punya niat. Seorang penyerang punya niat, dan di hadapannya CRC tidak melindungi apa pun. Ketika yang dibutuhkan adalah keotentikan alih-alih integritas, Anda perlu konstruksi berkunci: generator HMAC menghasilkannya atas payload dan kunci apa pun, dan mengapa verifikasi tanda tangan webhook gagal menelusuri bagian-bagian yang biasa menjegal orang saat memasangnya ke endpoint sungguhan.

9. FAQ

Apakah CRC-16/CCITT sama dengan CRC-16/CCITT-FALSE?

Tidak, CRC-16/CCITT-FALSE dan CRC-16/CCITT adalah varian yang berbeda. CCITT-FALSE adalah CRC-16/IBM-3740: init 0xFFFF, tanpa refleksi, nilai check 0x29B1. Varian yang biasanya dimaksud dengan CCITT polos adalah CRC-16/KERMIT: init 0x0000, direfleksikan, check 0x2189. Keduanya berbagi polinomial 0x1021 dan tidak sepakat pada hal lain apa pun.

Mengapa kalkulator online berbeda hasilnya dengan perangkat saya?

Parameternya berbeda, hampir selalu begitu. Alatnya memakai satu varian sebagai default sementara perangkatnya mengimplementasikan varian lain. Jalankan byte ASCII 123456789 melalui keduanya, bandingkan kedua nilai check itu dengan tabel di bagian 4, dan parameter yang tidak cocok biasanya menunjukkan dirinya sendiri dalam waktu kurang dari satu menit.

Mengapa Modbus menempatkan byte rendah CRC lebih dulu?

Karena spesifikasinya memang menetapkan begitu, dan itu satu-satunya field dalam frame yang berperilaku demikian. Alamat register dan jumlah register bersifat big-endian; CRC di ekor tidak. Hitung CRC-16/MODBUS atas seluruh frame termasuk kedua byte itu lalu periksa apakah hasilnya 0x0000, alih-alih menyusun ulang urutannya sendiri.

Apa persisnya yang dibalik oleh refin dan refout?

Bit di dalam sebuah byte, tidak pernah byte di dalam sebuah pesan. refin membalik delapan bit setiap byte masukan sebelum diproses; refout membalik isi akhir register sebelum XOR terakhir. Keduanya independen dari endianness, yang mengatur bagaimana sebuah nilai multi-byte ditata di jalur transmisi.

Sebaiknya saya memakai CRC-16 atau CRC-32?

CRC-16 meleset pada kerusakan acak kira-kira satu kali dari 65.536, CRC-32 satu kali dari 4,3 miliar. Untuk frame serial pendek sepanjang beberapa lusin byte, CRC-16 sudah memadai dan biasanya memang diwajibkan protokolnya. Untuk berkas, frame jaringan, dan apa pun yang lebih besar dari beberapa kilobyte, pakai CRC-32.

Bisakah saya memakai CRC sebagai tanda tangan API?

Tidak, CRC tidak layak dipakai sebagai tanda tangan API. CRC bersifat linear, sehingga siapa pun yang mengubah payload bisa menghitung ulang nilai yang cocok, dan menambahkan empat byte pilihan bisa mencapai target CRC-32 mana pun yang Anda sebutkan. Tanda tangan membutuhkan kunci rahasia dan konstruksi non-linear. Pakai HMAC dengan SHA-256.

Bisakah data aslinya dipulihkan dari sebuah nilai CRC?

Tidak, sebuah nilai CRC tidak menyimpan cukup informasi untuk memulihkan data aslinya. CRC-16 memampatkan masukan apa pun menjadi 16 bit, sehingga tak terhingga banyaknya pesan berbagi nilai yang sama. Meski begitu, arah sebaliknya tetap berguna bagi penyerang: dari sebuah nilai target, Anda bisa menyusun pesan yang menghasilkannya, dan itulah persis alasan CRC tidak mengotentikasi apa pun.

Dokumen vendor hanya menulis “CRC-16”. Bagaimana cara memastikan parameternya?

Mintalah satu frame hasil tangkapan beserta CRC yang dihitung perangkat mereka untuk frame itu, lalu jalankan sapuan 32 kombinasi dari bagian 4 terhadap pasangan tersebut. Kalau lebih dari satu set parameter bertahan, ulangi dengan frame kedua dan simpan irisannya. Dua sampel hampir selalu cukup untuk menentukannya.

Tag: crc checksum modbus embedded data-integrity

Artikel Terkait

Lihat semua artikel