1#[cfg(feature = "std")]
2use std::hash::Hasher;
3#[cfg(not(feature = "std"))]
4use core::hash::Hasher;
5
6pub use util::make_table_crc32 as make_table;
7
8include!(concat!(env!("OUT_DIR"), "/crc32_constants.rs"));
9
10pub struct Digest {
11 table: [u32; 256],
12 initial: u32,
13 value: u32
14}
15
16pub trait Hasher32 {
17 fn reset(&mut self);
18 fn write(&mut self, bytes: &[u8]);
19 fn sum32(&self) -> u32;
20}
21
22pub fn update(mut value: u32, table: &[u32; 256], bytes: &[u8]) -> u32 {
23 value = !value;
24 for &i in bytes.iter() {
25 value = table[((value as u8) ^ i) as usize] ^ (value >> 8)
26 }
27 !value
28}
29
30pub fn checksum_ieee(bytes: &[u8]) -> u32 {
31 return update(0, &IEEE_TABLE, bytes);
32}
33
34pub fn checksum_castagnoli(bytes: &[u8]) -> u32 {
35 return update(0, &CASTAGNOLI_TABLE, bytes);
36}
37
38pub fn checksum_koopman(bytes: &[u8]) -> u32 {
39 return update(0, &KOOPMAN_TABLE, bytes);
40}
41
42impl Digest {
43 pub fn new(poly: u32) -> Digest {
44 Digest {
45 table: make_table(poly),
46 initial: 0,
47 value: 0
48 }
49 }
50
51 pub fn new_with_initial(poly: u32, initial: u32) -> Digest {
52 Digest {
53 table: make_table(poly),
54 initial: initial,
55 value: initial
56 }
57 }
58}
59
60impl Hasher32 for Digest {
61 fn reset(&mut self) {
62 self.value = self.initial;
63 }
64 fn write(&mut self, bytes: &[u8]) {
65 self.value = update(self.value, &self.table, bytes);
66 }
67 fn sum32(&self) -> u32 {
68 self.value
69 }
70}
71
72impl Hasher for Digest {
74 fn write(&mut self, bytes: &[u8]) {
75 Hasher32::write(self, bytes);
76 }
77
78 fn finish(&self) -> u64 {
79 self.sum32() as u64
80 }
81}