CRC16 Hash Generator

Hash text, raw hex bytes or a file and read every CRC-16 variant at the same time. MODBUS, CCITT, XMODEM, KERMIT, DNP3 and 23 more, plus your own polynomial, so you stop guessing which one your device speaks.

CRC-16 checksum console

CRC-16/MODBUS
0000

Type or paste something and all 28 variants update as you go.

Every variant on the current input

Parameters follow the Rocksoft model. Check is the value each variant gives for the string 123456789.

VariantPolyInitReflectXorOutCheckYour input
CRC-16/ARCCRC-16, LHA, ARC archives, many PLC libraries80050000yes0000BB3D·
CRC-16/MODBUSModbus RTU serial framing8005FFFFyes00004B37·
CRC-16/USBUSB 2.0 data packets8005FFFFyesFFFFB4C8·
CRC-16/MAXIM-DOW1-Wire devices, iButton, DS2xxx parts80050000yesFFFF44C2·
CRC-16/UMTSBUYPASS, VERIFONE payment terminals80050000no0000FEE8·
CRC-16/CMSSome radio telemetry stacks8005FFFFno0000AEE7·
CRC-16/DDS-110DDS 120 signal generator serial protocol8005800Dno00009ECF·
CRC-16/IBM-3740CCITT-FALSE, AUTOSAR, most tools labelled CCITT1021FFFFno000029B1·
CRC-16/XMODEMZMODEM, ACORN, LTE, CRC-16/V-41-MSB10210000no000031C3·
CRC-16/KERMITBluetooth, the real CCITT, V-41-LSB10210000yes00002189·
CRC-16/IBM-SDLCX-25, ISO-HDLC, PPP FCS, CRC-B1021FFFFyesFFFF906E·
CRC-16/MCRF4XXMicrochip RFID transponders1021FFFFyes00006F91·
CRC-16/GENIBUSDARC, EPC Gen 2 tags, I-CODE1021FFFFnoFFFFD64E·
CRC-16/GSMGSM control channel blocks10210000noFFFFCE3C·
CRC-16/RIELLORiello UPS serial link1021B2AAyes000063D0·
CRC-16/TMS37157TI TMS37157 transponder102189ECyes000026B1·
CRC-16/ISO-IEC-14443-3-ACRC-A, Mifare and NFC type A1021C6C6yes0000BF05·
CRC-16/SPI-FUJITSUAUG-CCITT, Fujitsu SPI boot loaders10211D0Fno0000E5CC·
CRC-16/DNPDNP3 SCADA link layer blocks3D650000yesFFFFEA82·
CRC-16/EN-13757Wireless M-Bus meters3D650000noFFFFC2B7·
CRC-16/CDMA2000CDMA2000 air interfaceC867FFFFno00004C06·
CRC-16/PROFIBUSIEC 60870-5-1 telecontrol1DCFFFFFnoFFFFA819·
CRC-16/T10-DIFSCSI Data Integrity Field on 520 byte sectors8BB70000no0000D0DB·
CRC-16/TELEDISKTeledisk floppy imagesA0970000no00000FB3·
CRC-16/NRSC-5HD Radio broadcast frames080BFFFFyes0000A066·
CRC-16/M17M17 amateur digital radio5935FFFFno0000772B·
CRC-16/DECT-RDECT cordless, R-CRC-1605890000no0001007E·
CRC-16/DECT-XDECT cordless, X-CRC-1605890000no0000007F·

One name, twenty-eight answers

Someone hands you a serial frame and a checksum, tells you the device uses CRC16, and the number your code produces looks nothing like theirs. Neither of you made a mistake. CRC16 names a width, not an algorithm, and the published catalogue holds more than a hundred sixteen bit variants that share the name.

Take the string 123456789. Under CRC-16/MODBUS it hashes to 4B37. Under CRC-16/XMODEM it is 31C3. Under CRC-16/KERMIT, which uses the same polynomial as XMODEM, it is 2189. Same input, same width, three unrelated numbers.

Most CRC pages pick one variant, label it CRC16 and leave you to work out why your value differs. This one runs all 28 at once and lets you paste the value you expected, so the table tells you which parameter set the other side is running.

Five parameters describe any of them

Ross Williams wrote the model everyone still uses. Five numbers pin a variant down completely:

Every variant in the table above differs only in those five fields. The Custom option in the selector exposes them directly, so a vendor datasheet listing an odd init like B2AA takes seconds to reproduce.

The check value is the fastest way to identify a library

Each catalogued variant publishes the CRC of the nine ASCII bytes 123456789. That single number identifies the parameter set. Run those nine characters through whatever library your firmware links against, look up the result in the Check column, and you know exactly what you have been calling CRC16.

The trap is a library that says CCITT. CRC-16/IBM-3740 has been shipped under the CCITT name for decades even though it starts at FFFF, while the variant the ITU actually specified starts at zero with reflection and now goes by KERMIT. Check 29B1 against 2189 and the label stops mattering.

Byte order breaks more integrations than the polynomial does

A Modbus RTU read request looks like this on the wire:

01 03 00 00 00 0A C5 CD
slave 01, function 03, start 0000, count 000A, then two CRC bytes

Feed the first six bytes into the Hex tab with MODBUS selected and you get CDC5. The frame carries C5 CD. Nothing is wrong: Modbus transmits the CRC low byte first, so the value you compute reads backwards against the capture. That is why the result panel prints both byte orders under the headline number, and why the match field flags a hit with the bytes swapped instead of reporting no match.

Leave the CRC bytes attached and run the whole eight byte frame through MODBUS again. The answer is 0000. Appending the checksum in the order the protocol expects drives the register to a fixed residue, which is how receivers verify a frame without recomputing and comparing. A zero there means the frame survived the wire.

Which variant belongs to which world

Industrial serial buses
Modbus RTU uses CRC-16/MODBUS on every frame. DNP3 runs CRC-16/DNP over each 16 byte data block rather than the whole message, so a full frame needs several values. Profibus and IEC 60870-5-1 sit on their own polynomial.
File transfer that predates the internet
XMODEM-CRC and ZMODEM use CRC-16/XMODEM. Kermit uses the reflected version with the same polynomial. Both still turn up in bootloaders and device firmware upload paths, long after the modems went away.
Contactless cards and RFID
ISO/IEC 14443 type A tags, meaning most Mifare deployments, use CRC-A with init C6C6. Type B uses CRC-16/IBM-SDLC. Microchip RFID parts use MCRF4XX, and EPC Gen 2 tags use GENIBUS.
Storage and buses
USB 2.0 data packets carry CRC-16/USB. The T10 Data Integrity Field on 520 byte SCSI sectors uses polynomial 0x8BB7. 1-Wire temperature sensors and iButton keys use MAXIM-DOW.
Archives and legacy formats
LHA archives and the old ARC format use CRC-16/ARC, which plenty of PLC vendors ship as simply CRC-16. Teledisk floppy images have their own polynomial, 0xA097, and nothing else uses it.

Writing the loop yourself

A table driven CRC-16 is about fifteen lines. Build a 256 entry table from the polynomial, then fold one byte at a time into the register, reflecting the byte first when the variant asks for it. This page uses that structure, which is why a 500 MB file finishes without the tab going grey.

Two mistakes account for most broken implementations. The first is reflecting bytes on input but forgetting the final register reflection, which gives a value that looks plausible and matches nothing. The second is confusing the normal and reversed forms of the polynomial: 0x8005 and 0xA001 describe the same divisor, one written for a left shifting loop and one for a right shifting loop. Feeding 0xA001 into a left shifting implementation produces a checksum no standard recognises.

The Custom panel takes the normal, left shifting form, which is what the Poly column shows for every row.

Where this page stops

No verification pass. Give it bytes and it returns a number. Deciding whether a frame is intact means either stripping the trailing CRC yourself and comparing, or including it and checking for the residue described above. Comparing a file against a published checksum belongs in Checksum Validator.

No widths other than 16. CRC-32 for archives and Ethernet lives on the CRC32 generator, and running one input through several unrelated algorithms belongs in the Hash Generator Suite.

No search for unknown parameters. If you hold a set of frames with their checksums but no datasheet, the match field only tests the 28 variants listed. Recovering an undocumented polynomial from sample data is a different job, and CRC RevEng is the tool built for it.

No block splitting. DNP3 checksums each 16 byte block separately, so pasting a whole DNP3 frame gives you a value the protocol never computes. Feed it one block at a time.

Files over 32 MB run the selected variant alone. Twenty-eight parameter sets across a multi gigabyte file takes long enough to look like a crash, so the table stops filling and the headline number keeps working.

CRC-16 questions that come up mid-debug

The mismatches people hit when two sides of a link disagree about a checksum.

Why does my CRC16 not match the one my device sends?

Three causes, in order of frequency. The variant differs, since CRC16 names a width rather than an algorithm. The byte order differs, because Modbus and several other protocols send the low byte first, so a computed CDC5 appears as C5 CD in a capture. Or the byte range differs, because the checksum covers a subset of the frame rather than all of it. Paste the value you expected into the match field and the table shows which variant produces it, including with the bytes swapped.

Which CRC16 does Modbus RTU use?

CRC-16/MODBUS: polynomial 0x8005, init FFFF, input and output both reflected, no final XOR. Its check value for the string 123456789 is 4B37. The result goes on the wire low byte first, which is the opposite of how the number reads, and the checksum covers every byte of the frame from the slave address up to the CRC field.

What is the difference between CCITT and CRC-16/CCITT-FALSE?

CCITT-FALSE, catalogued as CRC-16/IBM-3740, starts at FFFF with no reflection and gives 29B1 for the check string. The variant the ITU standard actually describes starts at zero with input and output reflected, is catalogued as CRC-16/KERMIT, and gives 2189. The false name stuck because an early reference implementation mislabelled it, and most tools offering CCITT hand you the IBM-3740 answer.

Is 0x8005 the same polynomial as 0xA001?

Yes. They are the same divisor written for opposite shift directions: 0xA001 is 0x8005 bit reversed, meant for a loop shifting right, while 0x8005 suits a loop shifting left. Modbus documentation quotes 0xA001 because the reference code shifts right. Mixing the two forms is one of the most common ways a hand written CRC ends up producing values nothing recognises.

Why is my CRC zero when I include the checksum bytes?

That is the design working. Appending the CRC in the byte order the protocol expects and running the register over the whole frame drives it to a fixed residue, zero for Modbus. Receivers check that instead of recomputing and comparing, since it costs one pass and no branch. A non zero residue means the frame changed on the way over.

Can a CRC16 be used to store passwords or verify a download from an untrusted source?

No. CRC is linear, so anyone editing your data can compensate for the change and keep the checksum valid without any key. Sixteen bits also means collisions turn up after roughly 300 random inputs. It catches line noise and nothing else. Password storage needs bcrypt or Argon2, and download verification needs SHA-256 published on a channel an attacker does not control.

How large a message can a CRC-16 protect?

Bursts of 16 bits or shorter are always caught, whatever the length. Beyond that the guaranteed error distance of a 16 bit polynomial falls as messages grow, and past that limit only the 1 in 65536 random figure applies. Industrial protocols cap frames in the low thousands of bytes for this reason. Long files are better served by CRC-32 or a real hash.

Does my file get uploaded when I use the File tab?

No. The CRC implementation is in this page script with no network call in the hashing path. Files are read locally through FileReader in 4 MB slices and folded into the register slice by slice. Load the page once and it keeps working with the tab offline.

How do I checksum bytes that are not text?

Use the Hex bytes tab. It reads pairs of hex digits with or without spaces and ignores 0x prefixes, commas and dashes, so a copied logic analyser capture pastes straight in. The Text tab encodes as UTF-8, which turns any byte above 0x7F into two or three bytes and gives a checksum no device produced.