// hash/crc32 — CRC-32 checksum. Pure ww. // // Same shape as lib/hash/crc16: per-byte inline polynomial shift, // no precomputed table. Slower than Hare's table-driven path by ~8x // per byte but produces identical answers. package crc32; def IEEE: u32 = 0xEDB88320u32; // gzip, PNG, zip, Ethernet def CASTAGNOLI: u32 = 0x82F63B78u32; // iSCSI, SCTP, SSE4.2 def KOOPMAN: u32 = 0xEB31D82Eu32; // small datasets // sum32 — fold `buf` under `poly` (reversed form). Initial cval is // ~0u32; per byte we mix in the low byte via 8 polynomial shifts and // XOR with the high three bytes shifted down. export fn sum32(buf: []u8, poly: u32) u32 = { let c: u32 = 0xFFFFFFFFu32; let i: i32 = 0; for (i < buf.len) { let t: u32 = (c & 0xFFu32) ^ (buf[i]: u32); let z: i32 = 0; for (z < 8) { if ((t & 1u32) == 1u32) { t = (t >> 1u32) ^ poly; } else { t = t >> 1u32; }; z += 1; }; c = t ^ (c >> 8u32); i += 1; }; return ~c; }; export fn sum32ieee(buf: []u8) u32 = { return sum32(buf, IEEE); }; export fn sum32castagnoli(buf: []u8) u32 = { return sum32(buf, CASTAGNOLI); }; export fn sum32koopman(buf: []u8) u32 = { return sum32(buf, KOOPMAN); };