4.7 KiB
CRC32 + Adler32 Checksums
Purpose
Fast non-cryptographic checksums for bit-packed payloads. crc32 implements the IEEE-802.3 / zlib polynomial (0xedb88320); adler32 implements the RFC 1950 algorithm. Both are designed to detect accidental corruption (single-bit flips, wire-level errors, dropped bytes), not adversarial tampering — for cryptographic integrity, use the AEAD or signed-bitschema primitives in @suaveplan/bitpacker-crypto's encrypted/ and signed/ modules.
The four wrappers (appendCrc32, verifyAndStripCrc32, appendAdler32, verifyAndStripAdler32) bookend a payload with a 4-byte big-endian checksum so framed bitpacker output can be transmitted over a noisy channel and integrity-checked at the receiving end. The wrappers throw on truncated input or checksum mismatch; the bare crc32 / adler32 functions return the raw 32-bit value for callers that want to integrate the check elsewhere.
Features
crc32(data)— IEEE-802.3 / zlib polynomial CRC32 with a precomputed 256-entry tableadler32(data)— RFC 1950 Adler32 with the standardMOD_ADLER = 65521primeappendCrc32/appendAdler32— append 4-byte big-endian checksumverifyAndStripCrc32/verifyAndStripAdler32— verify and strip 4-byte checksum, throwing on mismatch or short input- Pure JS, no dependencies, deterministic output, browser- and Node-safe
Usage: Basic Example
import { crc32, appendCrc32, verifyAndStripCrc32 } from "@suaveplan/bitpacker-crypto";
const payload = new Uint8Array([1, 2, 3, 4]);
const checksum = crc32(payload); // 0xb63cfbcd
const framed = appendCrc32(payload); // 8 bytes: payload + 4-byte CRC
const restored = verifyAndStripCrc32(framed); // -> [1, 2, 3, 4]
Usage: Advanced Example
import {
appendCrc32,
verifyAndStripCrc32,
appendAdler32,
verifyAndStripAdler32,
} from "@suaveplan/bitpacker-crypto";
// Frame a bit-packed payload, transmit, and validate on receive.
function transmit(payload: Uint8Array): Uint8Array {
return appendCrc32(payload);
}
function receive(framed: Uint8Array): Uint8Array {
try {
return verifyAndStripCrc32(framed);
} catch (err) {
// Caller decides: retransmit, drop, or escalate to a higher-level
// integrity check (signed-bitschema for adversarial channels).
throw err;
}
}
// Adler32 is faster but weaker; pick it for short payloads on trusted channels.
const cheap = appendAdler32(new Uint8Array([0xde, 0xad, 0xbe, 0xef]));
const back = verifyAndStripAdler32(cheap);
API Reference
crc32(data: Uint8Array): number
Returns the 32-bit unsigned CRC32 value of data using the IEEE-802.3 / zlib polynomial (0xedb88320). Uses a precomputed 256-entry table for one-byte-per-iteration throughput.
adler32(data: Uint8Array): number
Returns the 32-bit unsigned Adler32 value of data per RFC 1950 (a and b accumulators with MOD_ADLER = 65521).
appendCrc32(data: Uint8Array): Uint8Array
Returns a new array containing data followed by 4 big-endian bytes of crc32(data).
verifyAndStripCrc32(data: Uint8Array): Uint8Array
Returns the leading data.length - 4 bytes if the trailing 4 bytes match crc32(payload). Throws Error with "Data too short for CRC32 verification" if data.length < 4, or "CRC32 mismatch: expected X, got Y" on mismatch.
appendAdler32(data: Uint8Array): Uint8Array
Returns a new array containing data followed by 4 big-endian bytes of adler32(data).
verifyAndStripAdler32(data: Uint8Array): Uint8Array
Mirrors verifyAndStripCrc32 for Adler32. Same error semantics.
Implementation Notes
- CRC32 polynomial =
0xedb88320. This is the bit-reversed form of the standard IEEE-802.3 polynomial (0x04c11db7). The reversal is encoded in the table-precomputation loop (c & 1 ? POLY ^ (c >>> 1) : c >>> 1) so the streaming inner loop processes least-significant bits first, matching zlib / gzip / PNG. - Big-endian checksum framing. Both append wrappers write the 32-bit checksum as big-endian bytes, matching network byte order. The
verifyAndStripcounterparts read withgetUint32(offset, false)(false = big-endian). - Not cryptographically secure. A motivated attacker can construct collisions for both CRC32 and Adler32 in O(1). Use these for accidental-corruption detection only; use AEAD or signature primitives elsewhere in
@suaveplan/bitpacker-cryptofor adversarial integrity. - No allocation in the hot path.
crc32/adler32only allocate via the precomputedCRC32_TABLE.appendCrc32/appendAdler32allocate one output buffer;verifyAndStripCrc32/verifyAndStripAdler32allocate viaslicefor the returned payload.