1#[cfg(feature = "std")]
2use std::hash::Hasher;
3#[cfg(not(feature = "std"))]
4use core::hash::Hasher;
5
6pub use util::make_table_crc64 as make_table;
7
8include!(concat!(env!("OUT_DIR"), "/crc64_constants.rs"));
9
10pub struct Digest {
11 table: [u64; 256],
12 initial: u64,
13 value: u64
14}
15
16pub trait Hasher64 {
17 fn reset(&mut self);
18 fn write(&mut self, bytes: &[u8]);
19 fn sum64(&self) -> u64;
20}
21
22pub fn update(mut value: u64, table: &[u64; 256], bytes: &[u8]) -> u64 {
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_ecma(bytes: &[u8]) -> u64 {
31 return update(0, &ECMA_TABLE, bytes);
32}
33
34pub fn checksum_iso(bytes: &[u8]) -> u64 {
35 return update(0, &ISO_TABLE, bytes);
36}
37
38impl Digest {
39 pub fn new(poly: u64) -> Digest {
40 Digest {
41 table: make_table(poly),
42 initial: 0,
43 value: 0
44 }
45 }
46
47 pub fn new_with_initial(poly: u64, initial: u64) -> Digest {
48 Digest {
49 table: make_table(poly),
50 initial: initial,
51 value: initial
52 }
53 }
54}
55
56impl Hasher64 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 sum64(&self) -> u64 {
64 self.value
65 }
66}
67
68impl Hasher for Digest {
70 fn write(&mut self, bytes: &[u8]) {
71 Hasher64::write(self, bytes);
72 }
73
74 fn finish(&self) -> u64 {
75 self.sum64()
76 }
77}