pub struct Crc64 {
table: [u64; 256],
value: u64,
count: u32,
}
fn table_maker(polynomial: u64) -> [u64; 256] {
let mut table: [u64; 256] = [0; 256];
for i in 0..256 {
let mut v = i as u64;
for _ in 0..8 {
v = if v & 1 != 0 {
polynomial ^ (v >> 1)
} else {
v >> 1
}
}
table[i] = v;
}
table
}
impl Crc64 {
pub fn new() -> Crc64 {
let polynomial = 0xC96C5795D7870F42;
let c64 = Crc64 {
table: table_maker(polynomial),
value: 0xffffffffffffffff,
count: 0,
};
c64
}
pub fn reset(&mut self) {
self.value = 0xffffffffffffffff;
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 ^ 0xffffffffffffffffu64;
}
pub fn checksum(&mut self, buf: &[u8]) -> u64 {
self.reset();
self.update(buf);
self.finalize();
self.getsum()
}
pub fn getsum(&self) -> u64 {
self.value
}
pub fn bytecount(&self) -> u32 {
self.count
}
}
#[test]
fn crc32_test() {
let mut crc64 = Crc64::new();
crc64.checksum(b"0000");
assert_eq!(crc64.getsum(), 0x2B5C866A7CBEF446);
}