crc/
crc16.rs

1#[cfg(feature = "std")]
2use std::hash::Hasher;
3#[cfg(not(feature = "std"))]
4use core::hash::Hasher;
5
6pub use util::make_table_crc16 as make_table;
7
8include!(concat!(env!("OUT_DIR"), "/crc16_constants.rs"));
9
10pub struct Digest {
11    table: [u16; 256],
12    initial: u16,
13    value: u16
14}
15
16pub trait Hasher16 {
17    fn reset(&mut self);
18    fn write(&mut self, bytes: &[u8]);
19    fn sum16(&self) -> u16;
20}
21
22pub fn update(mut value: u16, table: &[u16; 256], bytes: &[u8]) -> u16 {
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_x25(bytes: &[u8]) -> u16 {
31    return update(0, &X25_TABLE, bytes);
32}
33
34pub fn checksum_usb(bytes: &[u8]) -> u16 {
35    return update(0, &USB_TABLE, bytes);
36}
37
38impl Digest {
39    pub fn new(poly: u16) -> Digest {
40        Digest {
41            table: make_table(poly),
42            initial: 0,
43            value: 0
44        }
45    }
46
47    pub fn new_with_initial(poly: u16, initial: u16) -> Digest {
48        Digest {
49            table: make_table(poly),
50            initial: initial,
51            value: initial
52        }
53    }
54}
55
56impl Hasher16 for Digest {
57    fn reset(&mut self) {
58        self.value = self.initial;
59    }
60    fn write(&mut self, bytes: &[u8]) {
61        self.value = update(self.value, &self.table, bytes);
62    }
63    fn sum16(&self) -> u16 {
64        self.value
65    }
66}
67
68/// Implementation of std::hash::Hasher so that types which #[derive(Hash)] can hash with Digest.
69impl Hasher for Digest {
70    fn write(&mut self, bytes: &[u8]) {
71        Hasher16::write(self, bytes);
72    }
73
74    fn finish(&self) -> u64 {
75        self.sum16() as u64
76    }
77}