const CRC32_POLY: u32 = 0x04C11DB7;
const CRC32_TABLE: [u32; 256] = {
let mut table = [0u32; 256];
let mut i: usize = 0;
while i < 256 {
let mut crc = (i as u32) << 24;
let mut j = 0;
while j < 8 {
if crc & 0x80000000 != 0 {
crc = (crc << 1) ^ CRC32_POLY;
} else {
crc <<= 1;
}
j += 1;
}
table[i] = crc;
i += 1;
}
table
};
#[must_use]
pub fn crc32_mpeg2(data: &[u8]) -> u32 {
let mut crc: u32 = 0;
for &byte in data {
let index = ((crc >> 24) ^ u32::from(byte)) as usize;
crc = (crc << 8) ^ CRC32_TABLE[index & 0xFF];
}
crc
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
#[ignore]
fn test_crc32_empty() {
assert_eq!(crc32_mpeg2(&[]), 0);
}
#[test]
#[ignore]
fn test_crc32_known_vector() {
let data = b"123456789";
let crc = crc32_mpeg2(data);
assert_ne!(crc, 0);
assert_eq!(crc, crc32_mpeg2(data));
}
#[test]
#[ignore]
fn test_crc32_single_byte() {
let crc = crc32_mpeg2(&[0x00]);
assert_eq!(crc, CRC32_TABLE[0]);
}
#[test]
#[ignore]
fn test_crc32_deterministic() {
let data = b"FFV1 lossless video codec";
let c1 = crc32_mpeg2(data);
let c2 = crc32_mpeg2(data);
assert_eq!(c1, c2);
}
#[test]
#[ignore]
fn test_crc32_different_data() {
let a = crc32_mpeg2(b"hello");
let b = crc32_mpeg2(b"world");
assert_ne!(a, b);
}
}