A practical guide to defining and validating checksums in FastProto.
FastProto provides a single annotation @Checksum to describe:
During encode, FastProto computes and writes the checksum automatically. During decode, it recomputes and validates.
start (inclusive) and length (bytes).offset where the checksum value resides.type and value byteOrder.[start, start + length) (checksum value itself is excluded).offset points to the first byte of the checksum field.type (CRC8=1B, CRC16=2B, CRC32=4B, CRC64=8B).@Checksum(start = <start>, length = <length>, offset = <storeOffset>, type = <Type>, byteOrder = <ByteOrder>)start: start byte index (inclusive)length: number of bytes to includeoffset: where to write/read the checksum valuetype: algorithm, e.g. CRC8, CRC8_SMBUS, CRC8_MAXIM, CRC16, CRC16_MODBUS, CRC16_CCITT, CRC32, CRC32C, CRC64_ECMA182, CRC64_ISO, XOR8, LRC8byteOrder: affects only how the checksum value is written/read (multi-byte), not the calculation| Type | Width | Polynomial | Init | Refin/Refout | XorOut | Notes |
|---|---|---|---|---|---|---|
| CRC8 | 8 | 0x07 | 0x00 | false/false | 0x00 | SMBus-PEC base |
| CRC8_SMBUS | 8 | 0x07 | 0x00 | false/false | 0x00 | Alias of CRC8(0x07,0x00) |
| CRC8_MAXIM | 8 | 0x31 (reflected 0x8C) | 0x00 | true/true | 0x00 | Dallas/Maxim |
| XOR8 | 8 | — | — | — | — | Byte-wise XOR (BCC) |
| LRC8 | 8 | — | — | — | — | Two's complement of sum |
| CRC16 (IBM) | 16 | 0x8005 | 0x0000 | true/true | 0x0000 | Also known as CRC-16/IBM |
| CRC16_MODBUS | 16 | 0x8005 | 0xFFFF | true/true | 0x0000 | MODBUS RTU |
| CRC16_CCITT | 16 | 0x1021 | 0xFFFF | false/false | 0x0000 | CCITT-FALSE |
| CRC32 (IEEE) | 32 | 0x04C11DB7 | 0xFFFFFFFF | true/true | 0xFFFFFFFF | Ethernet/ZIP |
| CRC32C | 32 | 0x1EDC6F41 | 0xFFFFFFFF | true/true | 0xFFFFFFFF | Castagnoli |
| CRC64_ECMA182 | 64 | 0x42F0E1EBA9EA3693 | 0x0000000000000000 | false/false | 0x0000000000000000 | ECMA-182 |
| CRC64_ISO | 64 | 0x000000000000001B | 0xFFFFFFFFFFFFFFFF | true/true | 0xFFFFFFFFFFFFFFFF | ISO |
import org.indunet.fastproto.ByteOrder;
import org.indunet.fastproto.annotation.*;
public class Packet {
@UInt8Type(offset = 0) int b1;
@UInt8Type(offset = 1) int b2;
@UInt8Type(offset = 2) int b3;
@UInt8Type(offset = 3) int b4;
@UInt8Type(offset = 4) int b5;
@Checksum(start = 0, length = 5, offset = 5, type = Checksum.Type.CRC16, byteOrder = ByteOrder.LITTLE)
int crc16;
}You can also compute checksums without annotations:
import org.indunet.fastproto.annotation.Checksum;
import org.indunet.fastproto.checksum.ChecksumUtils;
byte[] bytes = new byte[]{0x31,0x32,0x33,0x34,0x35};
long v1 = ChecksumUtils.calculate(bytes, 0, 5, Checksum.Type.CRC16);
int v2 = ChecksumUtils.crc16(bytes) & 0xFFFF;[start, start+length) disjoint from the checksum storage bytes [offset, offset+width).byteOrder to match the on‑wire representation of the checksum value.@Checksum per checksum field; avoid overlapping ranges.DecodingException, recompute the expected checksum and compare against the stored bytes with the specified byteOrder.