crcany_core/model/
bytewise.rs

1use crate::crc::Crc;
2use crate::model::bitwise::BitwiseModel;
3use crate::spec::Spec;
4use crate::util::{ones, reverse};
5
6pub struct BytewiseModel {
7    model: BitwiseModel,
8    // table for byte-wise calculation
9    pub table: [u128; 256],
10}
11
12impl BytewiseModel {
13    pub fn reflect(&self) -> bool {
14        self.model.reflect()
15    }
16
17    pub fn reverse(&self) -> bool {
18        self.model.reverse()
19    }
20
21    pub fn width(&self) -> u16 {
22        self.model.width()
23    }
24
25    pub fn xorout(&self) -> u128 {
26        self.model.xorout()
27    }
28
29    pub fn init(&self) -> u128 {
30        self.model.init()
31    }
32
33    fn fill_table(&mut self) {
34        for k in 0..256_usize {
35            let byte = k as _;
36            let mut crc = self.model.add_bytes(0, &[byte][..]);
37            if self.model.reverse() {
38                crc = reverse(crc, self.model.width());
39            }
40            if self.model.width() < 8 && !self.model.reflect() {
41                crc <<= 8 - self.model.width();
42            }
43            self.table[k] = crc;
44        }
45    }
46
47    pub fn from_spec(spec: Spec) -> BytewiseModel {
48        let mut me = BytewiseModel {
49            model: BitwiseModel::from_spec(spec),
50            table: [0; 256],
51        };
52        me.fill_table();
53        me
54    }
55}
56
57impl Crc for BytewiseModel {
58    type Int = u128;
59
60    fn init(&self) -> u128 {
61        self.init() as _
62    }
63
64    fn add_bytes(&self, mut crc: u128, bytes: &[u8]) -> u128 {
65        if bytes.is_empty() {
66            return crc;
67        }
68
69        if self.model.reverse() {
70            crc = reverse(crc, self.model.width());
71        }
72
73        if self.model.reflect() {
74            crc &= ones(self.model.width());
75            for byte in bytes {
76                crc = (crc >> 8) ^ self.table[(crc ^ (*byte as u128)) as u8 as usize];
77            }
78        } else if self.model.width() < 8 {
79            let shift = 8 - self.model.width();
80            crc <<= shift;
81            for byte in bytes {
82                crc = self.table[(crc ^ (*byte as u128)) as usize];
83            }
84            crc >>= shift;
85        } else {
86            let shift = self.model.width() - 8;
87            for byte in bytes {
88                crc = (crc << 8) ^ self.table[(((crc >> shift) ^ (*byte as u128)) as u8) as usize];
89            }
90            crc &= ones(self.model.width());
91        }
92
93        if self.model.reverse() {
94            crc = reverse(crc, self.model.width());
95        }
96
97        crc as _
98    }
99}