1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
pub const CASTAGNOLI: u32 = 0x82f63b78; pub const IEEE: u32 = 0xedb88320; pub const KOOPMAN: u32 = 0xeb31d82e; lazy_static! { pub static ref IEEE_TABLE: [u32; 256] = make_table(IEEE); pub static ref CASTAGNOLI_TABLE: [u32; 256] = make_table(CASTAGNOLI); pub static ref KOOPMAN_TABLE: [u32; 256] = make_table(KOOPMAN); } pub struct Digest { table: [u32; 256], initial: u32, value: u32 } pub trait Hasher32 { fn reset(&mut self); fn write(&mut self, bytes: &[u8]); fn sum32(&self) -> u32; } pub fn make_table(poly: u32) -> [u32; 256] { let mut table = [0u32; 256]; for i in 0..256 { let mut value = i as u32; for _ in 0..8 { value = if (value & 1) == 1 { (value >> 1) ^ poly } else { value >> 1 } } table[i] = value; } table } pub fn update(mut value: u32, table: &[u32; 256], bytes: &[u8]) -> u32 { value = !value; for &i in bytes.iter() { value = table[((value as u8) ^ i) as usize] ^ (value >> 8) } !value } pub fn checksum_ieee(bytes: &[u8]) -> u32 { return update(0, &IEEE_TABLE, bytes); } pub fn checksum_castagnoli(bytes: &[u8]) -> u32 { return update(0, &CASTAGNOLI_TABLE, bytes); } pub fn checksum_koopman(bytes: &[u8]) -> u32 { return update(0, &KOOPMAN_TABLE, bytes); } impl Digest { pub fn new(poly: u32) -> Digest { Digest { table: make_table(poly), initial: 0, value: 0 } } pub fn new_with_initial(poly: u32, initial: u32) -> Digest { Digest { table: make_table(poly), initial: initial, value: initial } } } impl Hasher32 for Digest { fn reset(&mut self) { self.value = self.initial; } fn write(&mut self, bytes: &[u8]) { self.value = update(self.value, &self.table, bytes); } fn sum32(&self) -> u32 { self.value } }