44 lines
1.5 KiB
TypeScript
44 lines
1.5 KiB
TypeScript
|
|
/**
|
||
|
|
* @module utils/crc32c
|
||
|
|
* @description CRC-32C (Castagnoli, polynomial 0x1EDC6F41, reflected 0x82F63B78)
|
||
|
|
* — the storage-industry frame checksum (ext4, iSCSI, SCTP, LSM segment files).
|
||
|
|
* Used to frame generation-fact segments: every appended record carries the
|
||
|
|
* CRC-32C of its payload, so a torn tail (crash mid-append) or bit rot is
|
||
|
|
* DETECTED at scan time and never silently read as data.
|
||
|
|
*
|
||
|
|
* Table-driven, dependency-free reference implementation. Native providers may
|
||
|
|
* substitute a hardware-accelerated (SSE4.2 / ARMv8 CRC) implementation — the
|
||
|
|
* polynomial is the contract, byte-identical results required.
|
||
|
|
*/
|
||
|
|
|
||
|
|
/** The 256-entry lookup table for the reflected CRC-32C polynomial. */
|
||
|
|
const TABLE: Uint32Array = (() => {
|
||
|
|
const table = new Uint32Array(256)
|
||
|
|
for (let n = 0; n < 256; n++) {
|
||
|
|
let c = n
|
||
|
|
for (let k = 0; k < 8; k++) {
|
||
|
|
c = c & 1 ? 0x82f63b78 ^ (c >>> 1) : c >>> 1
|
||
|
|
}
|
||
|
|
table[n] = c >>> 0
|
||
|
|
}
|
||
|
|
return table
|
||
|
|
})()
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Compute the CRC-32C checksum of a byte buffer.
|
||
|
|
*
|
||
|
|
* Known-answer vectors (RFC 3720 appendix / the standard test suite):
|
||
|
|
* - ASCII "123456789" → 0xE3069283
|
||
|
|
* - 32 zero bytes → 0x8A9136AA
|
||
|
|
*
|
||
|
|
* @param bytes - The payload to checksum.
|
||
|
|
* @returns The CRC-32C as an unsigned 32-bit integer.
|
||
|
|
*/
|
||
|
|
export function crc32c(bytes: Uint8Array): number {
|
||
|
|
let crc = 0xffffffff
|
||
|
|
for (let i = 0; i < bytes.length; i++) {
|
||
|
|
crc = TABLE[(crc ^ bytes[i]) & 0xff] ^ (crc >>> 8)
|
||
|
|
}
|
||
|
|
return (crc ^ 0xffffffff) >>> 0
|
||
|
|
}
|