↑Programmieren in Rust
pub mod crc32 { const POLYNOMIAL: u32 = 0xEDB88320; pub struct CRC32 { lookup: [u32; 256] } impl CRC32 { pub fn new() -> Self { let mut lookup = [0; 256]; for i in 0..lookup.len() { let mut crc = i as u32; for _ in 0..8 { let a = (!(crc & 1)).wrapping_add(1); crc = (crc >> 1) ^ (a & POLYNOMIAL); } lookup[i] = crc; } Self {lookup} } pub fn hash(&self, data: &[u8], previous: u32) -> u32 { let mut crc: u32 = !previous; for byte in data { let index = ((crc as u8) ^ byte) as usize; crc = (crc >> 8) ^ self.lookup[index]; } !crc } } } #[cfg(test)] mod crc32_test { // Die Werte sind geprüft mit binascii.crc32 // aus der Python-Standardbibliothek. const TEST_VECTORS: [(u32, &[u8]); 14] = [ (0x00000000, b""), (0xd202ef8d, b"\x00"), (0x41d912ff, b"\x00\x00"), (0xff000000, b"\xff"), (0xffff0000, b"\xff\xff"), (0xffffff00, b"\xff\xff\xff"), (0xffffffff, b"\xff\xff\xff\xff"), (0xd2fd1072, b"\xff\xff\xff\xff\xff"), (0xe8b7be43, b"a"), (0x078a19d7, b"aa"), (0x9e83486d, b"ab"), (0x2ca74a14, b"ba"), (0x8587d865, b"abcde"), (0xaeef2a50, b"abcdefgh") ]; #[test] fn test() { let crc = crate::crc32::CRC32::new(); for (expected, data) in TEST_VECTORS { assert_eq!(crc.hash(data, 0), expected); } assert_eq!(0x9e83486d, crc.hash(b"", crc.hash(b"ab", 0))); assert_eq!(0x9e83486d, crc.hash(b"b", crc.hash(b"a", 0))); assert_eq!(0x8587d865, crc.hash(b"e", crc.hash(b"abcd", 0))); assert_eq!(0x8587d865, crc.hash(b"de", crc.hash(b"abc", 0))); assert_eq!(0xaeef2a50, crc.hash(b"efgh", crc.hash(b"abcd", 0))); assert_eq!(0xaeef2a50, crc.hash(b"fgh", crc.hash(b"abcde", 0))); let mut value = 0; for x in 0..u16::MAX { value = crc.hash(&u16::to_le_bytes(x), value); } assert_eq!(0xc7624fe6, value); } } fn main() { let crc = crc32::CRC32::new(); let data = b"Tee"; println!("{:08x}", crc.hash(data, 0)); }