crc/
crc32.rs

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
72/// Implementation of std::hash::Hasher so that types which #[derive(Hash)] can hash with Digest.
73impl 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}