const CRC_TABLE: [u32; 256] = make_crc_table();
const fn make_crc_table() -> [u32; 256] {
let mut table = [0u32; 256];
let mut i = 0usize;
while i < 256 {
let mut c = i as u32;
let mut k = 0;
while k < 8 {
c = if c & 1 != 0 {
0xEDB8_8320 ^ (c >> 1)
} else {
c >> 1
};
k += 1;
}
table[i] = c;
i += 1;
}
table
}
pub fn crc32(bytes: &[u8]) -> u32 {
let mut crc: u32 = 0xFFFF_FFFF;
for &b in bytes {
crc = CRC_TABLE[((crc ^ b as u32) & 0xFF) as usize] ^ (crc >> 8);
}
crc ^ 0xFFFF_FFFF
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn known_vectors() {
assert_eq!(crc32(b""), 0x0000_0000);
assert_eq!(crc32(b"123456789"), 0xCBF4_3926);
}
#[test]
fn detects_bit_flips() {
let a = crc32(b"the quick brown fox");
let mut mangled = b"the quick brown fox".to_vec();
mangled[5] ^= 0x40;
assert_ne!(a, crc32(&mangled));
}
}