1
+ use crate :: table:: crc128_table;
1
2
use crate :: util:: crc128;
3
+ use crate :: * ;
2
4
use crc_catalog:: Algorithm ;
3
5
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
+ }
7
62
8
63
const fn init ( algorithm : & Algorithm < u128 > , initial : u128 ) -> u128 {
9
64
if algorithm. refin {
@@ -23,146 +78,133 @@ const fn finalize(algorithm: &Algorithm<u128>, mut crc: u128) -> u128 {
23
78
crc ^ algorithm. xorout
24
79
}
25
80
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 > (
70
82
mut crc : u128 ,
71
- reflect : bool ,
72
- table : & [ [ u128 ; 256 ] ; 16 ] ,
83
+ algorithm : & Algorithm < u128 > ,
84
+ table : & [ [ u128 ; 256 ] ; L ] ,
73
85
bytes : & [ u8 ] ,
74
86
) -> u128 {
75
- let mut i = 0 ;
76
87
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 {
78
93
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 ) ;
112
112
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
+ }
113
165
i += 16 ;
114
166
}
167
+ }
115
168
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
+ }
120
183
}
121
184
} 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
+ } ;
159
192
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
+ }
164
205
}
165
206
}
207
+
166
208
crc
167
209
}
168
210
@@ -175,14 +217,14 @@ mod test {
175
217
#[ test]
176
218
fn correctness ( ) {
177
219
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
+ ] ;
186
228
187
229
pub const CRC_82_DARC_NONREFLEX : Algorithm < u128 > = Algorithm {
188
230
width : 82 ,
0 commit comments