TestBench.tools

CRC-16 Modbus Calculator

Compute CRC-16/MODBUS over hex or ASCII input, with LE/BE byte order.

9 bytes

CRC-16/MODBUS
0x4B37
Bytes (little-endian)
37 4B
Bytes (big-endian)
4B 37
Decimal
19255

This tool computes the CRC-16/MODBUS checksum used by every Modbus RTU frame. Paste hex bytes or ASCII text and the 16-bit CRC appears instantly, together with the little-endian byte pair you append to the frame. The reference check: ASCII 123456789 0x4B37.

How it works

CRC-16/MODBUS is a cyclic redundancy check with width 16, polynomial 0x8005, initial register value 0xFFFF, reflected input and output, and no final XOR. Because both input and output are reflected, practical implementations process the register right-to-left with the reversed polynomial 0xA001: XOR each message byte into the low byte of the register, then for each of the eight bits shift right and XOR with 0xA001 whenever a 1 falls out.

The CRC covers every byte of the RTU frame — slave address, function code and data — and is appended to the frame low byte first. A receiver recomputes the CRC over the same bytes and compares.

Worked example

A master reads 10 holding registers from unit 1 starting at address 0. The frame before the CRC is six bytes:

frame  : 01 03 00 00 00 0A
CRC-16 : 0xCDC5
on wire: 01 03 00 00 00 0A C5 CD (low byte first)

And the standard check value over the nine ASCII characters 123456789 (bytes 31 32 33 34 35 36 37 38 39) is 0x4B37 — try both in the calculator above.

Parameters

ParameterValueNotes
Width16
Polynomial0x80050xA001 in reflected form
Init0xFFFF
RefIn / RefOuttrue / true
XorOut0x0000
Check (“123456789”)0x4B37

C implementation

C
#include <stdint.h>
#include <stddef.h>

/* CRC-16/MODBUS: poly 0x8005 (reflected 0xA001), init 0xFFFF,
 * refin/refout, no final XOR. Append low byte first. */
uint16_t crc16_modbus(const uint8_t *data, size_t len)
{
    uint16_t crc = 0xFFFF;
    for (size_t i = 0; i < len; i++) {
        crc ^= data[i];
        for (int b = 0; b < 8; b++)
            crc = (crc & 1) ? (crc >> 1) ^ 0xA001 : crc >> 1;
    }
    return crc; /* "123456789" -> 0x4B37 */
}

FAQ

Which byte goes first in a Modbus RTU frame — CRC low or high?

The low byte is transmitted first. For the request 01 03 00 00 00 0A the CRC value is 0xCDC5, so the frame ends with C5 CD. Use the little-endian result row when appending the CRC to a frame.

What parameters define CRC-16/MODBUS?

Width 16, polynomial 0x8005, initial value 0xFFFF, input and output both reflected, and no final XOR. In reflected implementations the polynomial appears as 0xA001.

Why does my CRC match the calculator but the device still rejects the frame?

The most common causes are byte order (the CRC must be appended low byte first) and including or excluding the wrong bytes — the CRC covers every byte of the RTU frame from the address up to, but not including, the CRC itself.

How can I verify this calculator?

The standard check value for the ASCII string 123456789 is 0x4B37. Type it in ASCII mode and compare. This value is pinned in this site's automated test suite.

Is my data uploaded anywhere?

No. The calculation runs entirely in your browser in JavaScript. Nothing you type ever leaves your machine.

Related tools