Skip to content

Commit 7d19578

Browse files
committed
Use common const generic Crc impls
Signed-off-by: akhilles <[email protected]>
1 parent 06fda3a commit 7d19578

22 files changed

+859
-1473
lines changed

src/crc128.rs

Lines changed: 179 additions & 137 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,64 @@
1+
use crate::table::crc128_table;
12
use crate::util::crc128;
3+
use crate::*;
24
use crc_catalog::Algorithm;
35

4-
mod bytewise;
5-
mod nolookup;
6-
mod slice16;
6+
impl<const L: usize> Crc<u128, Table<L>>
7+
where
8+
Table<L>: private::Sealed,
9+
{
10+
pub const fn new(algorithm: &'static Algorithm<u128>) -> Self {
11+
Self {
12+
algorithm,
13+
data: crc128_table(algorithm.width, algorithm.poly, algorithm.refin),
14+
}
15+
}
16+
17+
pub const fn checksum(&self, bytes: &[u8]) -> u128 {
18+
let mut crc = init(self.algorithm, self.algorithm.init);
19+
crc = self.update(crc, bytes);
20+
finalize(self.algorithm, crc)
21+
}
22+
23+
const fn update(&self, crc: u128, bytes: &[u8]) -> u128 {
24+
update_table(crc, self.algorithm, &self.data, bytes)
25+
}
26+
27+
pub const fn digest(&self) -> Digest<u128, Table<L>> {
28+
self.digest_with_initial(self.algorithm.init)
29+
}
30+
31+
/// Construct a `Digest` with a given initial value.
32+
///
33+
/// This overrides the initial value specified by the algorithm.
34+
/// The effects of the algorithm's properties `refin` and `width`
35+
/// are applied to the custom initial value.
36+
pub const fn digest_with_initial(&self, initial: u128) -> Digest<u128, Table<L>> {
37+
let value = init(self.algorithm, initial);
38+
Digest::new(self, value)
39+
}
40+
41+
pub const fn table(&self) -> &<Table<L> as Implementation>::Data<u128> {
42+
&self.data
43+
}
44+
}
45+
46+
impl<'a, const L: usize> Digest<'a, u128, Table<L>>
47+
where
48+
Table<L>: private::Sealed,
49+
{
50+
const fn new(crc: &'a Crc<u128, Table<L>>, value: u128) -> Self {
51+
Digest { crc, value }
52+
}
53+
54+
pub fn update(&mut self, bytes: &[u8]) {
55+
self.value = self.crc.update(self.value, bytes);
56+
}
57+
58+
pub const fn finalize(self) -> u128 {
59+
finalize(self.crc.algorithm, self.value)
60+
}
61+
}
762

863
const fn init(algorithm: &Algorithm<u128>, initial: u128) -> u128 {
964
if algorithm.refin {
@@ -23,146 +78,133 @@ const fn finalize(algorithm: &Algorithm<u128>, mut crc: u128) -> u128 {
2378
crc ^ algorithm.xorout
2479
}
2580

26-
const fn update_nolookup(mut crc: u128, algorithm: &Algorithm<u128>, bytes: &[u8]) -> u128 {
27-
let poly = if algorithm.refin {
28-
let poly = algorithm.poly.reverse_bits();
29-
poly >> (128u8 - algorithm.width)
30-
} else {
31-
algorithm.poly << (128u8 - algorithm.width)
32-
};
33-
34-
let mut i = 0;
35-
if algorithm.refin {
36-
while i < bytes.len() {
37-
let to_crc = (crc ^ bytes[i] as u128) & 0xFF;
38-
crc = crc128(poly, algorithm.refin, to_crc) ^ (crc >> 8);
39-
i += 1;
40-
}
41-
} else {
42-
while i < bytes.len() {
43-
let to_crc = ((crc >> 120) ^ bytes[i] as u128) & 0xFF;
44-
crc = crc128(poly, algorithm.refin, to_crc) ^ (crc << 8);
45-
i += 1;
46-
}
47-
}
48-
crc
49-
}
50-
51-
const fn update_bytewise(mut crc: u128, reflect: bool, table: &[u128; 256], bytes: &[u8]) -> u128 {
52-
let mut i = 0;
53-
if reflect {
54-
while i < bytes.len() {
55-
let table_index = ((crc ^ bytes[i] as u128) & 0xFF) as usize;
56-
crc = table[table_index] ^ (crc >> 8);
57-
i += 1;
58-
}
59-
} else {
60-
while i < bytes.len() {
61-
let table_index = (((crc >> 120) ^ bytes[i] as u128) & 0xFF) as usize;
62-
crc = table[table_index] ^ (crc << 8);
63-
i += 1;
64-
}
65-
}
66-
crc
67-
}
68-
69-
const fn update_slice16(
81+
const fn update_table<const L: usize>(
7082
mut crc: u128,
71-
reflect: bool,
72-
table: &[[u128; 256]; 16],
83+
algorithm: &Algorithm<u128>,
84+
table: &[[u128; 256]; L],
7385
bytes: &[u8],
7486
) -> u128 {
75-
let mut i = 0;
7687
let len = bytes.len();
77-
if reflect {
88+
let mut i = 0;
89+
let reflect = algorithm.refin;
90+
91+
// Process 16 bytes at a time when L=16
92+
if L == 16 {
7893
while i + 16 <= len {
79-
let current0 = bytes[i] ^ crc as u8;
80-
let current1 = bytes[i + 1] ^ (crc >> 8) as u8;
81-
let current2 = bytes[i + 2] ^ (crc >> 16) as u8;
82-
let current3 = bytes[i + 3] ^ (crc >> 24) as u8;
83-
let current4 = bytes[i + 4] ^ (crc >> 32) as u8;
84-
let current5 = bytes[i + 5] ^ (crc >> 40) as u8;
85-
let current6 = bytes[i + 6] ^ (crc >> 48) as u8;
86-
let current7 = bytes[i + 7] ^ (crc >> 56) as u8;
87-
let current8 = bytes[i + 8] ^ (crc >> 64) as u8;
88-
let current9 = bytes[i + 9] ^ (crc >> 72) as u8;
89-
let current10 = bytes[i + 10] ^ (crc >> 80) as u8;
90-
let current11 = bytes[i + 11] ^ (crc >> 88) as u8;
91-
let current12 = bytes[i + 12] ^ (crc >> 96) as u8;
92-
let current13 = bytes[i + 13] ^ (crc >> 104) as u8;
93-
let current14 = bytes[i + 14] ^ (crc >> 112) as u8;
94-
let current15 = bytes[i + 15] ^ (crc >> 120) as u8;
95-
96-
crc = table[15][current0 as usize]
97-
^ table[14][current1 as usize]
98-
^ table[13][current2 as usize]
99-
^ table[12][current3 as usize]
100-
^ table[11][current4 as usize]
101-
^ table[10][current5 as usize]
102-
^ table[9][current6 as usize]
103-
^ table[8][current7 as usize]
104-
^ table[7][current8 as usize]
105-
^ table[6][current9 as usize]
106-
^ table[5][current10 as usize]
107-
^ table[4][current11 as usize]
108-
^ table[3][current12 as usize]
109-
^ table[2][current13 as usize]
110-
^ table[1][current14 as usize]
111-
^ table[0][current15 as usize];
94+
if reflect {
95+
// XOR the first 16 bytes with the current CRC value
96+
let current0 = bytes[i] ^ (crc as u8);
97+
let current1 = bytes[i + 1] ^ ((crc >> 8) as u8);
98+
let current2 = bytes[i + 2] ^ ((crc >> 16) as u8);
99+
let current3 = bytes[i + 3] ^ ((crc >> 24) as u8);
100+
let current4 = bytes[i + 4] ^ ((crc >> 32) as u8);
101+
let current5 = bytes[i + 5] ^ ((crc >> 40) as u8);
102+
let current6 = bytes[i + 6] ^ ((crc >> 48) as u8);
103+
let current7 = bytes[i + 7] ^ ((crc >> 56) as u8);
104+
let current8 = bytes[i + 8] ^ ((crc >> 64) as u8);
105+
let current9 = bytes[i + 9] ^ ((crc >> 72) as u8);
106+
let current10 = bytes[i + 10] ^ ((crc >> 80) as u8);
107+
let current11 = bytes[i + 11] ^ ((crc >> 88) as u8);
108+
let current12 = bytes[i + 12] ^ ((crc >> 96) as u8);
109+
let current13 = bytes[i + 13] ^ ((crc >> 104) as u8);
110+
let current14 = bytes[i + 14] ^ ((crc >> 112) as u8);
111+
let current15 = bytes[i + 15] ^ ((crc >> 120) as u8);
112112

113+
crc = table[0][current15 as usize]
114+
^ table[1][current14 as usize]
115+
^ table[2][current13 as usize]
116+
^ table[3][current12 as usize]
117+
^ table[4][current11 as usize]
118+
^ table[5][current10 as usize]
119+
^ table[6][current9 as usize]
120+
^ table[7][current8 as usize]
121+
^ table[8][current7 as usize]
122+
^ table[9][current6 as usize]
123+
^ table[10][current5 as usize]
124+
^ table[11][current4 as usize]
125+
^ table[12][current3 as usize]
126+
^ table[13][current2 as usize]
127+
^ table[14][current1 as usize]
128+
^ table[15][current0 as usize];
129+
} else {
130+
// For non-reflected CRC128
131+
let current0 = bytes[i] ^ ((crc >> 120) as u8);
132+
let current1 = bytes[i + 1] ^ ((crc >> 112) as u8);
133+
let current2 = bytes[i + 2] ^ ((crc >> 104) as u8);
134+
let current3 = bytes[i + 3] ^ ((crc >> 96) as u8);
135+
let current4 = bytes[i + 4] ^ ((crc >> 88) as u8);
136+
let current5 = bytes[i + 5] ^ ((crc >> 80) as u8);
137+
let current6 = bytes[i + 6] ^ ((crc >> 72) as u8);
138+
let current7 = bytes[i + 7] ^ ((crc >> 64) as u8);
139+
let current8 = bytes[i + 8] ^ ((crc >> 56) as u8);
140+
let current9 = bytes[i + 9] ^ ((crc >> 48) as u8);
141+
let current10 = bytes[i + 10] ^ ((crc >> 40) as u8);
142+
let current11 = bytes[i + 11] ^ ((crc >> 32) as u8);
143+
let current12 = bytes[i + 12] ^ ((crc >> 24) as u8);
144+
let current13 = bytes[i + 13] ^ ((crc >> 16) as u8);
145+
let current14 = bytes[i + 14] ^ ((crc >> 8) as u8);
146+
let current15 = bytes[i + 15] ^ (crc as u8);
147+
148+
crc = table[0][current15 as usize]
149+
^ table[1][current14 as usize]
150+
^ table[2][current13 as usize]
151+
^ table[3][current12 as usize]
152+
^ table[4][current11 as usize]
153+
^ table[5][current10 as usize]
154+
^ table[6][current9 as usize]
155+
^ table[7][current8 as usize]
156+
^ table[8][current7 as usize]
157+
^ table[9][current6 as usize]
158+
^ table[10][current5 as usize]
159+
^ table[11][current4 as usize]
160+
^ table[12][current3 as usize]
161+
^ table[13][current2 as usize]
162+
^ table[14][current1 as usize]
163+
^ table[15][current0 as usize];
164+
}
113165
i += 16;
114166
}
167+
}
115168

116-
while i < len {
117-
let table_index = ((crc ^ bytes[i] as u128) & 0xFF) as usize;
118-
crc = table[0][table_index] ^ (crc >> 8);
119-
i += 1;
169+
// Process remaining bytes one at a time using the table (for L=1 and L=16)
170+
if L > 0 {
171+
if reflect {
172+
while i < len {
173+
let table_index = ((crc ^ bytes[i] as u128) & 0xFF) as usize;
174+
crc = table[0][table_index] ^ (crc >> 8);
175+
i += 1;
176+
}
177+
} else {
178+
while i < len {
179+
let table_index = (((crc >> 120) ^ bytes[i] as u128) & 0xFF) as usize;
180+
crc = table[0][table_index] ^ (crc << 8);
181+
i += 1;
182+
}
120183
}
121184
} else {
122-
while i + 16 <= len {
123-
let current0 = bytes[i] ^ (crc >> 120) as u8;
124-
let current1 = bytes[i + 1] ^ (crc >> 112) as u8;
125-
let current2 = bytes[i + 2] ^ (crc >> 104) as u8;
126-
let current3 = bytes[i + 3] ^ (crc >> 96) as u8;
127-
let current4 = bytes[i + 4] ^ (crc >> 88) as u8;
128-
let current5 = bytes[i + 5] ^ (crc >> 80) as u8;
129-
let current6 = bytes[i + 6] ^ (crc >> 72) as u8;
130-
let current7 = bytes[i + 7] ^ (crc >> 64) as u8;
131-
let current8 = bytes[i + 8] ^ (crc >> 56) as u8;
132-
let current9 = bytes[i + 9] ^ (crc >> 48) as u8;
133-
let current10 = bytes[i + 10] ^ (crc >> 40) as u8;
134-
let current11 = bytes[i + 11] ^ (crc >> 32) as u8;
135-
let current12 = bytes[i + 12] ^ (crc >> 24) as u8;
136-
let current13 = bytes[i + 13] ^ (crc >> 16) as u8;
137-
let current14 = bytes[i + 14] ^ (crc >> 8) as u8;
138-
let current15 = bytes[i + 15] ^ crc as u8;
139-
140-
crc = table[15][current0 as usize]
141-
^ table[14][current1 as usize]
142-
^ table[13][current2 as usize]
143-
^ table[12][current3 as usize]
144-
^ table[11][current4 as usize]
145-
^ table[10][current5 as usize]
146-
^ table[9][current6 as usize]
147-
^ table[8][current7 as usize]
148-
^ table[7][current8 as usize]
149-
^ table[6][current9 as usize]
150-
^ table[5][current10 as usize]
151-
^ table[4][current11 as usize]
152-
^ table[3][current12 as usize]
153-
^ table[2][current13 as usize]
154-
^ table[1][current14 as usize]
155-
^ table[0][current15 as usize];
156-
157-
i += 16;
158-
}
185+
// This section is for NoTable case (L=0)
186+
let poly = if reflect {
187+
let poly = algorithm.poly.reverse_bits();
188+
poly >> (128u8 - algorithm.width)
189+
} else {
190+
algorithm.poly << (128u8 - algorithm.width)
191+
};
159192

160-
while i < len {
161-
let table_index = (((crc >> 120) ^ bytes[i] as u128) & 0xFF) as usize;
162-
crc = table[0][table_index] ^ (crc << 8);
163-
i += 1;
193+
if reflect {
194+
while i < len {
195+
let to_crc = (crc ^ bytes[i] as u128) & 0xFF;
196+
crc = crc128(poly, reflect, to_crc) ^ (crc >> 8);
197+
i += 1;
198+
}
199+
} else {
200+
while i < len {
201+
let to_crc = ((crc >> 120) ^ bytes[i] as u128) & 0xFF;
202+
crc = crc128(poly, reflect, to_crc) ^ (crc << 8);
203+
i += 1;
204+
}
164205
}
165206
}
207+
166208
crc
167209
}
168210

@@ -175,14 +217,14 @@ mod test {
175217
#[test]
176218
fn correctness() {
177219
let data: &[&str] = &[
178-
"",
179-
"1",
180-
"1234",
181-
"123456789",
182-
"0123456789ABCDE",
183-
"01234567890ABCDEFGHIJK",
184-
"01234567890ABCDEFGHIJK01234567890ABCDEFGHIJK01234567890ABCDEFGHIJK01234567890ABCDEFGHIJK01234567890ABCDEFGHIJK01234567890ABCDEFGHIJK01234567890ABCDEFGHIJK01234567890ABCDEFGHIJK01234567890ABCDEFGHIJK01234567890ABCDEFGHIJK01234567890ABCDEFGHIJK01234567890ABCDEFGHIJK",
185-
];
220+
"",
221+
"1",
222+
"1234",
223+
"123456789",
224+
"0123456789ABCDE",
225+
"01234567890ABCDEFGHIJK",
226+
"01234567890ABCDEFGHIJK01234567890ABCDEFGHIJK01234567890ABCDEFGHIJK01234567890ABCDEFGHIJK01234567890ABCDEFGHIJK01234567890ABCDEFGHIJK01234567890ABCDEFGHIJK01234567890ABCDEFGHIJK01234567890ABCDEFGHIJK01234567890ABCDEFGHIJK01234567890ABCDEFGHIJK01234567890ABCDEFGHIJK",
227+
];
186228

187229
pub const CRC_82_DARC_NONREFLEX: Algorithm<u128> = Algorithm {
188230
width: 82,

0 commit comments

Comments
 (0)