const POLYNOMIAL: u32 = 0xEDB8_8320;
#[must_use]
pub fn crc32(bytes: &[u8]) -> u32 {
continue_crc32(0, bytes)
}
#[must_use]
pub fn continue_crc32(seed: u32, bytes: &[u8]) -> u32 {
let mut crc = !seed;
for byte in bytes {
crc ^= u32::from(*byte);
for _ in 0..8 {
let mask = 0_u32.wrapping_sub(crc & 1);
crc = (crc >> 1) ^ (POLYNOMIAL & mask);
}
}
!crc
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn the_published_check_value_is_reproduced() {
assert_eq!(crc32(b"123456789"), 0xCBF4_3926);
}
#[test]
fn the_empty_input_checksums_to_zero() {
assert_eq!(crc32(b""), 0);
}
#[test]
fn streaming_in_pieces_agrees_with_hashing_the_whole() {
let whole = b"the quick brown fox jumps over the lazy dog";
let mut running = 0;
for piece in whole.chunks(7) {
running = continue_crc32(running, piece);
}
assert_eq!(running, crc32(whole));
}
}