1use crcxx::crc16;
8use crcxx::crc32;
9
10const SLICES: usize = 16;
11
12const CRC_32: crc32::Crc<crc32::LookupTable256xN<SLICES>> =
13 crc32::Crc::<crc32::LookupTable256xN<SLICES>>::new(&crc32::catalog::CRC_32_ISO_HDLC);
14
15const CRC_16: crc16::Crc<crc16::LookupTable256xN<SLICES>> =
16 crc16::Crc::<crc16::LookupTable256xN<SLICES>>::new(&crc16::catalog::CRC_16_IBM_3740);
17
18pub fn crc32(bytes: &[u8]) -> u32 {
20 CRC_32.compute(bytes)
21}
22
23pub fn crc16(bytes: &[u8]) -> u16 {
29 CRC_16.compute(bytes)
30}
31
32pub struct Crc32Stream<'a>(crc32::ComputeMultipart<'a, crc32::LookupTable256xN<SLICES>>);
34
35impl Crc32Stream<'_> {
36 pub fn new() -> Crc32Stream<'static> {
37 Crc32Stream(CRC_32.compute_multipart())
38 }
39
40 pub fn update(&mut self, bytes: &[u8]) {
41 self.0.update(bytes);
42 }
43
44 pub fn value(&self) -> u32 {
45 self.0.value()
46 }
47}
48
49pub struct Crc16Stream<'a>(crc16::ComputeMultipart<'a, crc16::LookupTable256xN<SLICES>>);
51
52impl Crc16Stream<'_> {
53 pub fn new() -> Crc16Stream<'static> {
54 Crc16Stream(CRC_16.compute_multipart())
55 }
56
57 pub fn update(&mut self, bytes: &[u8]) {
58 self.0.update(bytes);
59 }
60
61 pub fn value(&self) -> u16 {
62 self.0.value()
63 }
64}
65
66#[cfg(test)]
67mod tests {
68 use super::*;
69
70 #[test]
74 fn the_algorithms_are_the_cataloged_ones() {
75 assert_eq!(crc32(b"123456789"), 0xCBF4_3926, "not CRC-32/ISO-HDLC");
76 assert_eq!(crc16(b"123456789"), 0x29B1, "not CRC-16/IBM-3740");
77 }
78
79 #[test]
81 fn streams_match_slices() {
82 let data: Vec<u8> = (0u8..=255).cycle().take(1000).collect();
83
84 let mut s32 = Crc32Stream::new();
85 let mut s16 = Crc16Stream::new();
86 for chunk in data.chunks(7) {
87 s32.update(chunk);
88 s16.update(chunk);
89 }
90 assert_eq!(s32.value(), crc32(&data));
91 assert_eq!(s16.value(), crc16(&data));
92 }
93}