↑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));
}