pub struct Crc32 {
table: [u32; 256],
value: u32,
count: u32,
}
fn table_maker(polynomial: u32) -> [u32; 256] {
let mut table: [u32; 256] = [0; 256];
for i in 0..256 {
let mut v = i as u32;
for _ in 0..8 {
v = if v & 1 != 0 {
polynomial ^ (v >> 1)
} else {
v >> 1
}
}
table[i] = v;
}
table
}
impl Crc32 {
pub fn new() -> Crc32 {
let polynomial = 0xEDB88320;
let c32 = Crc32 {
table: table_maker(polynomial),
value: 0xffffffff,
count: 0,
};
c32
}
pub fn reset(&mut self) {
self.value = 0xffffffff;
self.count = 0;
}
pub fn update(&mut self, buf: &[u8]) {
for &i in buf {
self.value = self.table[((self.value as u8) ^ i) as usize] ^ (self.value >> 8);
self.count += 1;
}
}
pub fn finalize(&mut self) {
self.value = self.value ^ 0xffffffff;
}
pub fn checksum(&mut self, buf: &[u8]) -> u32 {
self.reset();
self.update(buf);
self.finalize();
self.getsum()
}
pub fn getsum(&self) -> u32 {
self.value
}
pub fn bytecount(&self) -> u32 {
self.count
}
}
#[test]
fn crc32_test() {
let mut crc32 = Crc32::new();
crc32.checksum(b"0000");
assert_eq!(crc32.getsum(), 0x0C9BC472);
}