1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
use alloc::vec::Vec;
use alloc::fmt::{self, Formatter, Debug, Display};

/// This struct can help you compute a CRC-32 (or CRC-x where **x** is under `32`) value.
pub struct CRCu32 {
    by_table: bool,
    poly: u32,
    lookup_table: [u32; 256],
    sum: u32,
    pub(crate) bits: u8,
    high_bit: u32,
    mask: u32,
    initial: u32,
    final_xor: u32,
    reflect: bool,
    reorder: bool,
}

impl Debug for CRCu32 {
    #[inline]
    fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
        if self.by_table {
            impl_debug_for_struct!(CRCu64, f, self, let .lookup_table = self.lookup_table.as_ref(), (.sum, "0x{:08X}", self.sum), .bits, (.initial, "0x{:08X}", self.initial), (.final_xor, "0x{:08X}", self.final_xor), .reflect, .reorder);
        } else {
            impl_debug_for_struct!(CRCu64, f, self, (.poly, "0x{:08X}", self.poly), (.sum, "0x{:08X}", self.sum), .bits, (.initial, "0x{:08X}", self.initial), (.final_xor, "0x{:08X}", self.final_xor), .reflect, .reorder);
        }
    }
}

impl Display for CRCu32 {
    #[inline]
    fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
        f.write_fmt(format_args!("0x{:01$X}", self.get_crc(), ((self.bits as f64 + 3f64) / 4f64) as usize))
    }
}

impl CRCu32 {
    /// Create a `CRCu32` instance by providing the length of bits, expression, reflection, an initial value and a final xor value.
    pub fn create_crc(poly: u32, bits: u8, initial: u32, final_xor: u32, reflect: bool) -> CRCu32 {
        debug_assert!(bits <= 32 && bits > 0);

        if bits % 8 == 0 {
            let lookup_table = if reflect {
                Self::crc_reflect_table(poly)
            } else {
                Self::crc_table(poly, bits)
            };

            Self::create_crc_with_exists_lookup_table(lookup_table, bits, initial, final_xor, reflect)
        } else {
            Self::create(false, [0u32; 256], poly, bits, initial, final_xor, reflect)
        }
    }

    #[inline]
    pub(crate) fn create_crc_with_exists_lookup_table(lookup_table: [u32; 256], bits: u8, initial: u32, final_xor: u32, reflect: bool) -> CRCu32 {
        debug_assert!(bits % 8 == 0);

        Self::create(true, lookup_table, 0, bits, initial, final_xor, reflect)
    }

    #[inline]
    fn create(by_table: bool, lookup_table: [u32; 256], mut poly: u32, bits: u8, initial: u32, final_xor: u32, reflect: bool) -> CRCu32 {
        let high_bit = 1 << (bits as u32 - 1);
        let mask = ((high_bit - 1) << 1) | 1;

        let sum = if reflect {
            Self::reflect_function(high_bit, initial)
        } else {
            initial
        };

        if !by_table && reflect {
            poly = Self::reflect_function(high_bit, poly);
        }

        CRCu32 {
            by_table,
            poly,
            lookup_table,
            sum,
            bits,
            high_bit,
            mask,
            initial,
            final_xor,
            reflect,
            reorder: false,
        }
    }

    #[inline]
    fn reflect_function(high_bit: u32, n: u32) -> u32 {
        let mut i = high_bit;
        let mut j = 1;
        let mut out = 0;

        while i != 0 {
            if n & i != 0 {
                out |= j;
            }

            j <<= 1;
            i >>= 1;
        }

        out
    }

    #[inline]
    fn reflect_method(&self, n: u32) -> u32 {
        Self::reflect_function(self.high_bit, n)
    }

    /// Digest some data.
    pub fn digest<T: ?Sized + AsRef<[u8]>>(&mut self, data: &T) {
        if self.by_table {
            if self.bits == 8 {
                for &n in data.as_ref() {
                    let index = (self.sum as u8 ^ n) as usize;
                    self.sum = self.lookup_table[index];
                }
            } else {
                if self.reflect {
                    for &n in data.as_ref() {
                        let index = ((self.sum as u8) ^ n) as usize;
                        self.sum = (self.sum >> 8) ^ self.lookup_table[index];
                    }
                } else {
                    for &n in data.as_ref() {
                        let index = ((self.sum >> ((self.bits - 8) as u32)) as u8 ^ n) as usize;
                        self.sum = (self.sum << 8) ^ self.lookup_table[index];
                    }
                }
            }
        } else {
            if self.reflect {
                for &n in data.as_ref() {
                    let n = super::crc_u8::CRCu8::reflect_function(0x80, n);

                    let mut i = 0x80;

                    while i != 0 {
                        let mut bit = self.sum & self.high_bit;

                        self.sum <<= 1;

                        if n & i != 0 {
                            bit ^= self.high_bit;
                        }


                        if bit != 0 {
                            self.sum ^= self.poly;
                        }

                        i >>= 1;
                    }
                }
            } else {
                for &n in data.as_ref() {
                    let mut i = 0x80;

                    while i != 0 {
                        let mut bit = self.sum & self.high_bit;

                        self.sum <<= 1;

                        if n & i != 0 {
                            bit ^= self.high_bit;
                        }


                        if bit != 0 {
                            self.sum ^= self.poly;
                        }

                        i >>= 1;
                    }
                }
            }
        }
    }

    /// Reset the sum.
    pub fn reset(&mut self) {
        self.sum = self.initial;
    }

    /// Get the current CRC value (it always returns a `u32` value). You can continue calling `digest` method even after getting a CRC value.
    pub fn get_crc(&self) -> u32 {
        let sum = if self.by_table {
            (self.sum ^ self.final_xor) & self.mask
        } else {
            if self.reflect {
                (self.reflect_method(self.sum) ^ self.final_xor) & self.mask
            } else {
                (self.sum ^ self.final_xor) & self.mask
            }
        };

        if self.reorder {
            let mut new_sum = 0;

            let e = ((self.bits as f64 + 7f64) / 8f64) as u32;

            let e_dec = e - 1;

            for i in 0..e {
                new_sum |= ((sum >> ((e_dec - i) * 8)) & 0xFF) << (i * 8);
            }

            new_sum
        } else {
            sum
        }
    }

    /// Get the current CRC value (it always returns a vec instance with a length corresponding to the CRC bits). You can continue calling `digest` method even after getting a CRC value.
    pub fn get_crc_vec_le(&mut self) -> Vec<u8> {
        let e = ((self.bits as f64 + 7f64) / 8f64) as u32;

        let e_dec = e - 1;

        let mut vec = Vec::with_capacity(e as usize);

        let crc = self.get_crc();

        let o = e_dec * 8;

        for i in 0..e {
            vec.push((crc << (e_dec - i) * 8 >> o) as u8);
        }

        vec
    }

    /// Get the current CRC value (it always returns a vec instance with a length corresponding to the CRC bits). You can continue calling `digest` method even after getting a CRC value.
    pub fn get_crc_vec_be(&mut self) -> Vec<u8> {
        let e = ((self.bits as f64 + 7f64) / 8f64) as u32;

        let e_dec = e - 1;

        let mut vec = Vec::with_capacity(e as usize);

        let crc = self.get_crc();

        let o = e_dec * 8;

        for i in 0..e {
            vec.push((crc << i * 8 >> o) as u8);
        }

        vec
    }

    fn crc_reflect_table(poly_rev: u32) -> [u32; 256] {
        let mut lookup_table = [0u32; 256];

        for i in 0..=255 {
            let mut v = i as u32;

            for _ in 0..8u8 {
                if v & 1 != 0 {
                    v >>= 1;
                    v ^= poly_rev;
                } else {
                    v >>= 1;
                }
            }

            lookup_table[i] = v;
        }

        lookup_table
    }

    fn crc_table(poly: u32, bits: u8) -> [u32; 256] {
        let mut lookup_table = [0u32; 256];

        let mask1 = 1u32 << (bits - 1) as u32;

        let mask2 = ((mask1 - 1) << 1) | 1;

        for i in 0..=255 {
            let mut v = i as u32;

            for _ in 0..bits {
                if v & mask1 == 0 {
                    v <<= 1;
                } else {
                    v <<= 1;
                    v ^= poly;
                }
            }

            lookup_table[i] = v & mask2;
        }

        lookup_table
    }
}

const NO_REF_24_005D6DCB: [u32; 256] = [0u32, 6122955u32, 12245910u32, 15185501u32, 2677479u32, 7714604u32, 9568625u32, 13593786u32, 5354958u32, 841733u32, 15429208u32, 11928467u32, 7958313u32, 2360034u32, 12825791u32, 10410356u32, 10709916u32, 16647767u32, 1683466u32, 4513217u32, 9154939u32, 14081200u32, 3238637u32, 7079718u32, 15916626u32, 11514777u32, 4720068u32, 1402895u32, 14288053u32, 8874366u32, 6348579u32, 4043496u32, 1817331u32, 4642616u32, 10576229u32, 16518318u32, 3366932u32, 7212511u32, 9026434u32, 13948489u32, 4853565u32, 1532662u32, 15783083u32, 11385184u32, 6477274u32, 4175889u32, 14159436u32, 8741767u32, 12112239u32, 15056036u32, 133881u32, 6252338u32, 9440136u32, 13461059u32, 2805790u32, 7847381u32, 15295649u32, 11798890u32, 5488439u32, 971516u32, 12697158u32, 10277773u32, 8086992u32, 2492443u32, 3634662u32, 6953005u32, 9285232u32, 13681595u32, 2076417u32, 4375242u32, 10843287u32, 16259420u32, 6733864u32, 3911139u32, 14425022u32, 8484469u32, 5118671u32, 1275652u32, 16040281u32, 11119762u32, 9707130u32, 13202353u32, 3065324u32, 7579687u32, 12371101u32, 14788950u32, 401163u32, 5993152u32, 12954548u32, 10012287u32, 8351778u32, 2235881u32, 15561043u32, 11541656u32, 5745349u32, 706318u32, 2936597u32, 7447262u32, 9835651u32, 13334856u32, 267762u32, 5863481u32, 12504676u32, 14918575u32, 8223451u32, 2103056u32, 13082957u32, 10144902u32, 5611580u32, 577015u32, 15694762u32, 11671137u32, 9413769u32, 13814082u32, 3505951u32, 6820564u32, 10976878u32, 16389029u32, 1943032u32, 4245555u32, 14553415u32, 8617100u32, 6605521u32, 3778330u32, 16173984u32, 11249259u32, 4984886u32, 1146365u32, 7269324u32, 3376647u32, 13906010u32, 9002385u32, 4600107u32, 1793248u32, 16575165u32, 10585974u32, 4152834u32, 6435785u32, 8750484u32, 14215263u32, 1541349u32, 4909358u32, 11362163u32, 15741624u32, 13467728u32, 9498011u32, 7822278u32, 2766349u32, 15030967u32, 12072828u32, 6258977u32, 191722u32, 10237342u32, 12671061u32, 2551304u32, 8094659u32, 11857785u32, 15303346u32, 931055u32, 5462308u32, 7688511u32, 2637044u32, 13601449u32, 9627490u32, 6130648u32, 58899u32, 15159374u32, 12205445u32, 2417905u32, 7964986u32, 10370919u32, 12800684u32, 802326u32, 5329885u32, 11986304u32, 15435851u32, 14039715u32, 9131880u32, 7135541u32, 3247358u32, 16703556u32, 10718607u32, 4471762u32, 1660441u32, 8884077u32, 14344870u32, 4019451u32, 6306096u32, 11490698u32, 15874113u32, 1412636u32, 4776919u32, 5873194u32, 324577u32, 14894524u32, 12462199u32, 7423181u32, 2894086u32, 13344603u32, 9892496u32, 535524u32, 5588527u32, 11726962u32, 15703481u32, 2158851u32, 8232136u32, 10103445u32, 13059934u32, 16446902u32, 10983549u32, 4206112u32, 1917931u32, 13774673u32, 9388698u32, 6878407u32, 3512588u32, 11223160u32, 16133555u32, 1154030u32, 5043749u32, 8624799u32, 14612308u32, 3752201u32, 6565058u32, 4334809u32, 2050322u32, 16318287u32, 10850948u32, 7011902u32, 3642357u32, 13641128u32, 9259107u32, 1282327u32, 5176540u32, 11094657u32, 16000842u32, 3886064u32, 6694459u32, 8491110u32, 14482861u32, 14765893u32, 12329614u32, 6001875u32, 456984u32, 13211042u32, 9762921u32, 7556660u32, 3023871u32, 11598475u32, 15570752u32, 663837u32, 5721302u32, 9969772u32, 12930471u32, 2292730u32, 8361521u32];
const NO_REF_24_00800063: [u32; 256] = [0u32, 8388707u32, 8388773u32, 198u32, 8388905u32, 330u32, 396u32, 8389103u32, 8389169u32, 594u32, 660u32, 8389367u32, 792u32, 8389499u32, 8389565u32, 990u32, 8389633u32, 1122u32, 1188u32, 8389831u32, 1320u32, 8389963u32, 8390029u32, 1518u32, 1584u32, 8390227u32, 8390293u32, 1782u32, 8390425u32, 1914u32, 1980u32, 8390623u32, 8390753u32, 2050u32, 2244u32, 8390823u32, 2376u32, 8390955u32, 8391149u32, 2446u32, 2640u32, 8391219u32, 8391413u32, 2710u32, 8391545u32, 2842u32, 3036u32, 8391615u32, 3168u32, 8391683u32, 8391877u32, 3238u32, 8392009u32, 3370u32, 3564u32, 8392079u32, 8392273u32, 3634u32, 3828u32, 8392343u32, 3960u32, 8392475u32, 8392669u32, 4030u32, 8392865u32, 4290u32, 4100u32, 8392807u32, 4488u32, 8393195u32, 8393005u32, 4430u32, 4752u32, 8393459u32, 8393269u32, 4694u32, 8393657u32, 5082u32, 4892u32, 8393599u32, 5280u32, 8393923u32, 8393733u32, 5222u32, 8394121u32, 5610u32, 5420u32, 8394063u32, 8394385u32, 5874u32, 5684u32, 8394327u32, 6072u32, 8394715u32, 8394525u32, 6014u32, 6336u32, 8394915u32, 8394853u32, 6150u32, 8395241u32, 6538u32, 6476u32, 8395055u32, 8395505u32, 6802u32, 6740u32, 8395319u32, 7128u32, 8395707u32, 8395645u32, 6942u32, 8395969u32, 7330u32, 7268u32, 8395783u32, 7656u32, 8396171u32, 8396109u32, 7470u32, 7920u32, 8396435u32, 8396373u32, 7734u32, 8396761u32, 8122u32, 8060u32, 8396575u32, 8397089u32, 8514u32, 8580u32, 8397287u32, 8200u32, 8396907u32, 8396973u32, 8398u32, 8976u32, 8397683u32, 8397749u32, 9174u32, 8397369u32, 8794u32, 8860u32, 8397567u32, 9504u32, 8398147u32, 8398213u32, 9702u32, 8397833u32, 9322u32, 9388u32, 8398031u32, 8398609u32, 10098u32, 10164u32, 8398807u32, 9784u32, 8398427u32, 8398493u32, 9982u32, 10560u32, 8399139u32, 8399333u32, 10630u32, 8398953u32, 10250u32, 10444u32, 8399023u32, 8399729u32, 11026u32, 11220u32, 8399799u32, 10840u32, 8399419u32, 8399613u32, 10910u32, 8400193u32, 11554u32, 11748u32, 8400263u32, 11368u32, 8399883u32, 8400077u32, 11438u32, 12144u32, 8400659u32, 8400853u32, 12214u32, 8400473u32, 11834u32, 12028u32, 8400543u32, 12672u32, 8401379u32, 8401189u32, 12614u32, 8401065u32, 12490u32, 12300u32, 8401007u32, 8401841u32, 13266u32, 13076u32, 8401783u32, 12952u32, 8401659u32, 8401469u32, 12894u32, 8402305u32, 13794u32, 13604u32, 8402247u32, 13480u32, 8402123u32, 8401933u32, 13422u32, 14256u32, 8402899u32, 8402709u32, 14198u32, 8402585u32, 14074u32, 13884u32, 8402527u32, 8403425u32, 14722u32, 14660u32, 8403239u32, 14536u32, 8403115u32, 8403053u32, 14350u32, 15312u32, 8403891u32, 8403829u32, 15126u32, 8403705u32, 15002u32, 14940u32, 8403519u32, 15840u32, 8404355u32, 8404293u32, 15654u32, 8404169u32, 15530u32, 15468u32, 8403983u32, 8404945u32, 16306u32, 16244u32, 8404759u32, 16120u32, 8404635u32, 8404573u32, 15934u32];
const NO_REF_24_00864CFB: [u32; 256] = [0u32, 8801531u32, 9098509u32, 825846u32, 9692897u32, 1419802u32, 1651692u32, 10452759u32, 10584377u32, 2608578u32, 2839604u32, 11344079u32, 3303384u32, 11807523u32, 12104405u32, 4128302u32, 12930697u32, 4391538u32, 5217156u32, 13227903u32, 5679208u32, 13690003u32, 14450021u32, 5910942u32, 6606768u32, 14844747u32, 15604413u32, 6837830u32, 16197969u32, 7431594u32, 8256604u32, 16494759u32, 840169u32, 9084178u32, 8783076u32, 18463u32, 10434312u32, 1670131u32, 1434117u32, 9678590u32, 11358416u32, 2825259u32, 2590173u32, 10602790u32, 4109873u32, 12122826u32, 11821884u32, 3289031u32, 13213536u32, 5231515u32, 4409965u32, 12912278u32, 5929345u32, 14431610u32, 13675660u32, 5693559u32, 6823513u32, 15618722u32, 14863188u32, 6588335u32, 16513208u32, 8238147u32, 7417269u32, 16212302u32, 1680338u32, 10481449u32, 9664223u32, 1391140u32, 9061683u32, 788936u32, 36926u32, 8838341u32, 12067563u32, 4091408u32, 3340262u32, 11844381u32, 2868234u32, 11372785u32, 10555655u32, 2579964u32, 14478683u32, 5939616u32, 5650518u32, 13661357u32, 5180346u32, 13190977u32, 12967607u32, 4428364u32, 8219746u32, 16457881u32, 16234863u32, 7468436u32, 15633027u32, 6866552u32, 6578062u32, 14816117u32, 1405499u32, 9649856u32, 10463030u32, 1698765u32, 8819930u32, 55329u32, 803287u32, 9047340u32, 11858690u32, 3325945u32, 4072975u32, 12086004u32, 2561507u32, 10574104u32, 11387118u32, 2853909u32, 13647026u32, 5664841u32, 5958079u32, 14460228u32, 4446803u32, 12949160u32, 13176670u32, 5194661u32, 7454091u32, 16249200u32, 16476294u32, 8201341u32, 14834538u32, 6559633u32, 6852199u32, 15647388u32, 3360676u32, 11864927u32, 12161705u32, 4185682u32, 10527045u32, 2551230u32, 2782280u32, 11286707u32, 9619101u32, 1346150u32, 1577872u32, 10379115u32, 73852u32, 8875143u32, 9172337u32, 899466u32, 16124205u32, 7357910u32, 8182816u32, 16421083u32, 6680524u32, 14918455u32, 15678145u32, 6911546u32, 5736468u32, 13747439u32, 14507289u32, 5968354u32, 12873461u32, 4334094u32, 5159928u32, 13170435u32, 4167245u32, 12180150u32, 11879232u32, 3346363u32, 11301036u32, 2767959u32, 2532769u32, 10545498u32, 10360692u32, 1596303u32, 1360505u32, 9604738u32, 913813u32, 9157998u32, 8856728u32, 92259u32, 16439492u32, 8164415u32, 7343561u32, 16138546u32, 6897189u32, 15692510u32, 14936872u32, 6662099u32, 5986813u32, 14488838u32, 13733104u32, 5750795u32, 13156124u32, 5174247u32, 4352529u32, 12855018u32, 2810998u32, 11315341u32, 10498427u32, 2522496u32, 12124823u32, 4148844u32, 3397530u32, 11901793u32, 9135439u32, 862644u32, 110658u32, 8912057u32, 1606574u32, 10407765u32, 9590435u32, 1317464u32, 15706879u32, 6940164u32, 6651890u32, 14889737u32, 8145950u32, 16384229u32, 16161043u32, 7394792u32, 5123014u32, 13133629u32, 12910283u32, 4370992u32, 14535975u32, 5997020u32, 5707818u32, 13718737u32, 2504095u32, 10516836u32, 11329682u32, 2796649u32, 11916158u32, 3383173u32, 4130419u32, 12143240u32, 8893606u32, 129117u32, 876971u32, 9121104u32, 1331783u32, 9576124u32, 10389322u32, 1625009u32, 14908182u32, 6633453u32, 6925851u32, 15721184u32, 7380471u32, 16175372u32, 16402682u32, 8127489u32, 4389423u32, 12891860u32, 13119266u32, 5137369u32, 13704398u32, 5722165u32, 6015427u32, 14517560u32];
const NO_REF_32_000000AF: [u32; 256] = [0u32, 175u32, 350u32, 497u32, 700u32, 531u32, 994u32, 845u32, 1400u32, 1495u32, 1062u32, 1161u32, 1988u32, 1899u32, 1690u32, 1589u32, 2800u32, 2655u32, 2990u32, 2817u32, 2124u32, 2275u32, 2322u32, 2493u32, 3976u32, 3879u32, 3798u32, 3705u32, 3380u32, 3483u32, 3178u32, 3269u32, 5600u32, 5455u32, 5310u32, 5137u32, 5980u32, 6131u32, 5634u32, 5805u32, 4248u32, 4151u32, 4550u32, 4457u32, 4644u32, 4747u32, 4986u32, 5077u32, 7952u32, 8127u32, 7758u32, 7905u32, 7596u32, 7427u32, 7410u32, 7261u32, 6760u32, 6855u32, 6966u32, 7065u32, 6356u32, 6267u32, 6538u32, 6437u32, 11200u32, 11119u32, 10910u32, 10801u32, 10620u32, 10707u32, 10274u32, 10381u32, 11960u32, 11799u32, 12262u32, 12105u32, 11268u32, 11435u32, 11610u32, 11765u32, 8496u32, 8607u32, 8302u32, 8385u32, 9100u32, 8995u32, 8914u32, 8829u32, 9288u32, 9447u32, 9494u32, 9657u32, 9972u32, 9819u32, 10154u32, 9989u32, 15904u32, 16015u32, 16254u32, 16337u32, 15516u32, 15411u32, 15810u32, 15725u32, 15192u32, 15351u32, 14854u32, 15017u32, 14820u32, 14667u32, 14522u32, 14357u32, 13520u32, 13439u32, 13710u32, 13601u32, 13932u32, 14019u32, 14130u32, 14237u32, 12712u32, 12551u32, 12534u32, 12377u32, 13076u32, 13243u32, 12874u32, 13029u32, 22400u32, 22319u32, 22238u32, 22129u32, 21820u32, 21907u32, 21602u32, 21709u32, 21240u32, 21079u32, 21414u32, 21257u32, 20548u32, 20715u32, 20762u32, 20917u32, 23920u32, 24031u32, 23598u32, 23681u32, 24524u32, 24419u32, 24210u32, 24125u32, 22536u32, 22695u32, 22870u32, 23033u32, 23220u32, 23067u32, 23530u32, 23365u32, 16992u32, 17103u32, 17214u32, 17297u32, 16604u32, 16499u32, 16770u32, 16685u32, 18200u32, 18359u32, 17990u32, 18153u32, 17828u32, 17675u32, 17658u32, 17493u32, 18576u32, 18495u32, 18894u32, 18785u32, 18988u32, 19075u32, 19314u32, 19421u32, 19944u32, 19783u32, 19638u32, 19481u32, 20308u32, 20475u32, 19978u32, 20133u32, 31808u32, 31983u32, 32030u32, 32177u32, 32508u32, 32339u32, 32674u32, 32525u32, 31032u32, 31127u32, 30822u32, 30921u32, 31620u32, 31531u32, 31450u32, 31349u32, 30384u32, 30239u32, 30702u32, 30529u32, 29708u32, 29859u32, 30034u32, 30205u32, 29640u32, 29543u32, 29334u32, 29241u32, 29044u32, 29147u32, 28714u32, 28805u32, 27040u32, 26895u32, 26878u32, 26705u32, 27420u32, 27571u32, 27202u32, 27373u32, 27864u32, 27767u32, 28038u32, 27945u32, 28260u32, 28363u32, 28474u32, 28565u32, 25424u32, 25599u32, 25102u32, 25249u32, 25068u32, 24899u32, 24754u32, 24605u32, 26152u32, 26247u32, 26486u32, 26585u32, 25748u32, 25659u32, 26058u32, 25957u32];
const NO_REF_32_04C11DB7: [u32; 256] = [0u32, 79764919u32, 159529838u32, 222504665u32, 319059676u32, 398814059u32, 445009330u32, 507990021u32, 638119352u32, 583659535u32, 797628118u32, 726387553u32, 890018660u32, 835552979u32, 1015980042u32, 944750013u32, 1276238704u32, 1221641927u32, 1167319070u32, 1095957929u32, 1595256236u32, 1540665371u32, 1452775106u32, 1381403509u32, 1780037320u32, 1859660671u32, 1671105958u32, 1733955601u32, 2031960084u32, 2111593891u32, 1889500026u32, 1952343757u32, 2552477408u32, 2632100695u32, 2443283854u32, 2506133561u32, 2334638140u32, 2414271883u32, 2191915858u32, 2254759653u32, 3190512472u32, 3135915759u32, 3081330742u32, 3009969537u32, 2905550212u32, 2850959411u32, 2762807018u32, 2691435357u32, 3560074640u32, 3505614887u32, 3719321342u32, 3648080713u32, 3342211916u32, 3287746299u32, 3467911202u32, 3396681109u32, 4063920168u32, 4143685023u32, 4223187782u32, 4286162673u32, 3779000052u32, 3858754371u32, 3904687514u32, 3967668269u32, 881225847u32, 809987520u32, 1023691545u32, 969234094u32, 662832811u32, 591600412u32, 771767749u32, 717299826u32, 311336399u32, 374308984u32, 453813921u32, 533576470u32, 25881363u32, 88864420u32, 134795389u32, 214552010u32, 2023205639u32, 2086057648u32, 1897238633u32, 1976864222u32, 1804852699u32, 1867694188u32, 1645340341u32, 1724971778u32, 1587496639u32, 1516133128u32, 1461550545u32, 1406951526u32, 1302016099u32, 1230646740u32, 1142491917u32, 1087903418u32, 2896545431u32, 2825181984u32, 2770861561u32, 2716262478u32, 3215044683u32, 3143675388u32, 3055782693u32, 3001194130u32, 2326604591u32, 2389456536u32, 2200899649u32, 2280525302u32, 2578013683u32, 2640855108u32, 2418763421u32, 2498394922u32, 3769900519u32, 3832873040u32, 3912640137u32, 3992402750u32, 4088425275u32, 4151408268u32, 4197601365u32, 4277358050u32, 3334271071u32, 3263032808u32, 3476998961u32, 3422541446u32, 3585640067u32, 3514407732u32, 3694837229u32, 3640369242u32, 1762451694u32, 1842216281u32, 1619975040u32, 1682949687u32, 2047383090u32, 2127137669u32, 1938468188u32, 2001449195u32, 1325665622u32, 1271206113u32, 1183200824u32, 1111960463u32, 1543535498u32, 1489069629u32, 1434599652u32, 1363369299u32, 622672798u32, 568075817u32, 748617968u32, 677256519u32, 907627842u32, 853037301u32, 1067152940u32, 995781531u32, 51762726u32, 131386257u32, 177728840u32, 240578815u32, 269590778u32, 349224269u32, 429104020u32, 491947555u32, 4046411278u32, 4126034873u32, 4172115296u32, 4234965207u32, 3794477266u32, 3874110821u32, 3953728444u32, 4016571915u32, 3609705398u32, 3555108353u32, 3735388376u32, 3664026991u32, 3290680682u32, 3236090077u32, 3449943556u32, 3378572211u32, 3174993278u32, 3120533705u32, 3032266256u32, 2961025959u32, 2923101090u32, 2868635157u32, 2813903052u32, 2742672763u32, 2604032198u32, 2683796849u32, 2461293480u32, 2524268063u32, 2284983834u32, 2364738477u32, 2175806836u32, 2238787779u32, 1569362073u32, 1498123566u32, 1409854455u32, 1355396672u32, 1317987909u32, 1246755826u32, 1192025387u32, 1137557660u32, 2072149281u32, 2135122070u32, 1912620623u32, 1992383480u32, 1753615357u32, 1816598090u32, 1627664531u32, 1707420964u32, 295390185u32, 358241886u32, 404320391u32, 483945776u32, 43990325u32, 106832002u32, 186451547u32, 266083308u32, 932423249u32, 861060070u32, 1041341759u32, 986742920u32, 613929101u32, 542559546u32, 756411363u32, 701822548u32, 3316196985u32, 3244833742u32, 3425377559u32, 3370778784u32, 3601682597u32, 3530312978u32, 3744426955u32, 3689838204u32, 3819031489u32, 3881883254u32, 3928223919u32, 4007849240u32, 4037393693u32, 4100235434u32, 4180117107u32, 4259748804u32, 2310601993u32, 2373574846u32, 2151335527u32, 2231098320u32, 2596047829u32, 2659030626u32, 2470359227u32, 2550115596u32, 2947551409u32, 2876312838u32, 2788305887u32, 2733848168u32, 3165939309u32, 3094707162u32, 3040238851u32, 2985771188u32];
const NO_REF_32_814141AB: [u32; 256] = [0u32, 2168537515u32, 2210644733u32, 42107734u32, 2261173329u32, 126322170u32, 84215468u32, 2219067143u32, 2362231049u32, 227379362u32, 252644340u32, 2387495519u32, 168430936u32, 2336967923u32, 2311704485u32, 143166990u32, 2564346809u32, 429494802u32, 454758724u32, 2589610223u32, 505288680u32, 2673825347u32, 2648560917u32, 480023742u32, 336861872u32, 2505399067u32, 2547505229u32, 378968550u32, 2463293153u32, 328441674u32, 286333980u32, 2421185975u32, 2968577753u32, 833726322u32, 858989604u32, 2993841551u32, 909517448u32, 3078054691u32, 3052789877u32, 884253150u32, 1010577360u32, 3179114107u32, 3221220653u32, 1052683398u32, 3137006465u32, 1002154538u32, 960047484u32, 3094898903u32, 673723744u32, 2842260683u32, 2884368285u32, 715830838u32, 2934894897u32, 800043162u32, 757937100u32, 2892788327u32, 2766470249u32, 631619010u32, 656883348u32, 2791735103u32, 572667960u32, 2741205395u32, 2715941573u32, 547404654u32, 3768618009u32, 1642188210u32, 1667452644u32, 3793882959u32, 1717979208u32, 3878095331u32, 3852831413u32, 1692715806u32, 1819034896u32, 3979150523u32, 4021258221u32, 1861142086u32, 3937042753u32, 1810612458u32, 1768506300u32, 3894936087u32, 2021154720u32, 4181270027u32, 4223376733u32, 2063260918u32, 4273904625u32, 2147474010u32, 2105366796u32, 4231796903u32, 4105475753u32, 1979045634u32, 2004309076u32, 4130739711u32, 1920094968u32, 4080210771u32, 4054945797u32, 1894830510u32, 1347447488u32, 3507563371u32, 3549669437u32, 1389554070u32, 3600199313u32, 1473769274u32, 1431661676u32, 3558092231u32, 3701253065u32, 1574822498u32, 1600086324u32, 3726516383u32, 1515874200u32, 3675989555u32, 3650725221u32, 1490609358u32, 3364403577u32, 1237973202u32, 1263238020u32, 3389667887u32, 1313766696u32, 3473882243u32, 3448618965u32, 1288502910u32, 1145335920u32, 3305451995u32, 3347559053u32, 1187443494u32, 3263345697u32, 1136915850u32, 1094809308u32, 3221239671u32, 1073764761u32, 3242268722u32, 3284376420u32, 1115871951u32, 3334905288u32, 1200086115u32, 1157979957u32, 3292798622u32, 3435958416u32, 1301139771u32, 1326404205u32, 3461223366u32, 1242191041u32, 3410695530u32, 3385431612u32, 1216927639u32, 3638069792u32, 1503251339u32, 1528514781u32, 3663333750u32, 1579044465u32, 3747549146u32, 3722284172u32, 1553780007u32, 1410614057u32, 3579118210u32, 3621224916u32, 1452720255u32, 3537012600u32, 1402193619u32, 1360086405u32, 3494904878u32, 4042309440u32, 1907490539u32, 1932754365u32, 4067572758u32, 1983281937u32, 4151786170u32, 4126521836u32, 1958017095u32, 2084337225u32, 4252841954u32, 4294948020u32, 2126443807u32, 4210733592u32, 2075915187u32, 2033807589u32, 4168626510u32, 1747479801u32, 3915984210u32, 3958091268u32, 1789587375u32, 4008618152u32, 1873799427u32, 1831692885u32, 3966512126u32, 3840189936u32, 1705370715u32, 1730635533u32, 3865454246u32, 1646420385u32, 3814924298u32, 3789661020u32, 1621156599u32, 2694894976u32, 568431659u32, 593696637u32, 2720159446u32, 644223441u32, 2804371578u32, 2779108140u32, 618959495u32, 745282697u32, 2905431330u32, 2947538548u32, 787390431u32, 2863323352u32, 736860531u32, 694753829u32, 2821217166u32, 947390009u32, 3107538834u32, 3149644996u32, 989496687u32, 3200172648u32, 1073710019u32, 1031602325u32, 3158065470u32, 3031748400u32, 905285275u32, 930549197u32, 3057011814u32, 846334817u32, 3006483146u32, 2981218716u32, 821069879u32, 273691481u32, 2433839858u32, 2475946404u32, 315797519u32, 2526476040u32, 400012963u32, 357905909u32, 2484368478u32, 2627533392u32, 501070843u32, 526334125u32, 2652797190u32, 442121729u32, 2602270634u32, 2577005820u32, 416857431u32, 2290671840u32, 164208971u32, 189473309u32, 2315936694u32, 240002225u32, 2400150810u32, 2374886988u32, 214738919u32, 71576041u32, 2231724098u32, 2273831700u32, 113683135u32, 2189618616u32, 63155219u32, 21049157u32, 2147512046u32];

const REF_24_00DA6000: [u32; 256] = [0u32, 111808u32, 223616u32, 187712u32, 447232u32, 485312u32, 375424u32, 265792u32, 894464u32, 791232u32, 970624u32, 1014592u32, 750848u32, 704960u32, 531584u32, 632896u32, 1788928u32, 1767616u32, 1582464u32, 1675584u32, 1941248u32, 1846208u32, 2029184u32, 2048576u32, 1501696u32, 1531584u32, 1409920u32, 1324864u32, 1063168u32, 1150400u32, 1265792u32, 1238080u32, 3577856u32, 3615936u32, 3535232u32, 3425600u32, 3164928u32, 3276736u32, 3351168u32, 3315264u32, 3882496u32, 3836608u32, 3692416u32, 3793728u32, 4058368u32, 3955136u32, 4097152u32, 4141120u32, 3003392u32, 2908352u32, 3063168u32, 3082560u32, 2819840u32, 2798528u32, 2649728u32, 2742848u32, 2126336u32, 2213568u32, 2300800u32, 2273088u32, 2531584u32, 2561472u32, 2476160u32, 2391104u32, 7155712u32, 7111872u32, 7231872u32, 7335232u32, 7070464u32, 6969280u32, 6851200u32, 6897216u32, 6329856u32, 6365888u32, 6553472u32, 6441792u32, 6702336u32, 6812096u32, 6630528u32, 6592576u32, 7764992u32, 7850176u32, 7673216u32, 7643456u32, 7384832u32, 7412672u32, 7587456u32, 7500352u32, 8116736u32, 8023744u32, 7910272u32, 7931712u32, 8194304u32, 8175040u32, 8282240u32, 8377408u32, 6006784u32, 5905600u32, 5816704u32, 5862720u32, 6126336u32, 6082496u32, 6165120u32, 6268480u32, 5639680u32, 5749440u32, 5597056u32, 5559104u32, 5299456u32, 5335488u32, 5485696u32, 5374016u32, 4252672u32, 4280512u32, 4427136u32, 4340032u32, 4601600u32, 4686784u32, 4546176u32, 4516416u32, 5063168u32, 5043904u32, 5122944u32, 5218112u32, 4952320u32, 4859328u32, 4782208u32, 4803648u32, 14311424u32, 14406848u32, 14223744u32, 14204224u32, 14463744u32, 14485440u32, 14670464u32, 14577216u32, 14140928u32, 14054080u32, 13938560u32, 13966144u32, 13702400u32, 13672896u32, 13794432u32, 13879360u32, 12659712u32, 12622016u32, 12731776u32, 12841280u32, 13106944u32, 12995520u32, 12883584u32, 12919360u32, 13404672u32, 13450944u32, 13624192u32, 13522752u32, 13261056u32, 13364672u32, 13185152u32, 13141056u32, 15529984u32, 15551680u32, 15700352u32, 15607104u32, 15346432u32, 15441856u32, 15286912u32, 15267392u32, 14769664u32, 14740160u32, 14825344u32, 14910272u32, 15174912u32, 15088064u32, 15000704u32, 15028288u32, 16233472u32, 16122048u32, 16047488u32, 16083264u32, 15820544u32, 15782848u32, 15863424u32, 15972928u32, 16388608u32, 16492224u32, 16350080u32, 16305984u32, 16564480u32, 16610752u32, 16754816u32, 16653376u32, 12013568u32, 11986112u32, 11811200u32, 11898176u32, 11633408u32, 11548608u32, 11725440u32, 11755072u32, 12252672u32, 12272320u32, 12164992u32, 12069696u32, 12330240u32, 12423616u32, 12536960u32, 12515392u32, 11279360u32, 11380928u32, 11498880u32, 11452736u32, 11194112u32, 11238336u32, 11118208u32, 11014720u32, 10598912u32, 10489536u32, 10670976u32, 10708800u32, 10971392u32, 10935744u32, 10748032u32, 10859584u32, 8505344u32, 8420544u32, 8561024u32, 8590656u32, 8854272u32, 8826816u32, 8680064u32, 8767040u32, 9203200u32, 9296576u32, 9373568u32, 9352000u32, 9092352u32, 9112000u32, 9032832u32, 8937536u32, 10126336u32, 10170560u32, 10087808u32, 9984320u32, 10245888u32, 10347456u32, 10436224u32, 10390080u32, 9904640u32, 9868992u32, 9718656u32, 9830208u32, 9564416u32, 9455040u32, 9607296u32, 9645120u32];
const REF_32_82F63B78: [u32; 256] = [0u32, 4067132163u32, 3778769143u32, 324072436u32, 3348797215u32, 904991772u32, 648144872u32, 3570033899u32, 2329499855u32, 2024987596u32, 1809983544u32, 2575936315u32, 1296289744u32, 3207089363u32, 2893594407u32, 1578318884u32, 274646895u32, 3795141740u32, 4049975192u32, 51262619u32, 3619967088u32, 632279923u32, 922689671u32, 3298075524u32, 2592579488u32, 1760304291u32, 2075979607u32, 2312596564u32, 1562183871u32, 2943781820u32, 3156637768u32, 1313733451u32, 549293790u32, 3537243613u32, 3246849577u32, 871202090u32, 3878099393u32, 357341890u32, 102525238u32, 4101499445u32, 2858735121u32, 1477399826u32, 1264559846u32, 3107202533u32, 1845379342u32, 2677391885u32, 2361733625u32, 2125378298u32, 820201905u32, 3263744690u32, 3520608582u32, 598981189u32, 4151959214u32, 85089709u32, 373468761u32, 3827903834u32, 3124367742u32, 1213305469u32, 1526817161u32, 2842354314u32, 2107672161u32, 2412447074u32, 2627466902u32, 1861252501u32, 1098587580u32, 3004210879u32, 2688576843u32, 1378610760u32, 2262928035u32, 1955203488u32, 1742404180u32, 2511436119u32, 3416409459u32, 969524848u32, 714683780u32, 3639785095u32, 205050476u32, 4266873199u32, 3976438427u32, 526918040u32, 1361435347u32, 2739821008u32, 2954799652u32, 1114974503u32, 2529119692u32, 1691668175u32, 2005155131u32, 2247081528u32, 3690758684u32, 697762079u32, 986182379u32, 3366744552u32, 476452099u32, 3993867776u32, 4250756596u32, 255256311u32, 1640403810u32, 2477592673u32, 2164122517u32, 1922457750u32, 2791048317u32, 1412925310u32, 1197962378u32, 3037525897u32, 3944729517u32, 427051182u32, 170179418u32, 4165941337u32, 746937522u32, 3740196785u32, 3451792453u32, 1070968646u32, 1905808397u32, 2213795598u32, 2426610938u32, 1657317369u32, 3053634322u32, 1147748369u32, 1463399397u32, 2773627110u32, 4215344322u32, 153784257u32, 444234805u32, 3893493558u32, 1021025245u32, 3467647198u32, 3722505002u32, 797665321u32, 2197175160u32, 1889384571u32, 1674398607u32, 2443626636u32, 1164749927u32, 3070701412u32, 2757221520u32, 1446797203u32, 137323447u32, 4198817972u32, 3910406976u32, 461344835u32, 3484808360u32, 1037989803u32, 781091935u32, 3705997148u32, 2460548119u32, 1623424788u32, 1939049696u32, 2180517859u32, 1429367560u32, 2807687179u32, 3020495871u32, 1180866812u32, 410100952u32, 3927582683u32, 4182430767u32, 186734380u32, 3756733383u32, 763408580u32, 1053836080u32, 3434856499u32, 2722870694u32, 1344288421u32, 1131464017u32, 2971354706u32, 1708204729u32, 2545590714u32, 2229949006u32, 1988219213u32, 680717673u32, 3673779818u32, 3383336350u32, 1002577565u32, 4010310262u32, 493091189u32, 238226049u32, 4233660802u32, 2987750089u32, 1082061258u32, 1395524158u32, 2705686845u32, 1972364758u32, 2279892693u32, 2494862625u32, 1725896226u32, 952904198u32, 3399985413u32, 3656866545u32, 731699698u32, 4283874585u32, 222117402u32, 510512622u32, 3959836397u32, 3280807620u32, 837199303u32, 582374963u32, 3504198960u32, 68661723u32, 4135334616u32, 3844915500u32, 390545967u32, 1230274059u32, 3141532936u32, 2825850620u32, 1510247935u32, 2395924756u32, 2091215383u32, 1878366691u32, 2644384480u32, 3553878443u32, 565732008u32, 854102364u32, 3229815391u32, 340358836u32, 3861050807u32, 4117890627u32, 119113024u32, 1493875044u32, 2875275879u32, 3090270611u32, 1247431312u32, 2660249211u32, 1828433272u32, 2141937292u32, 2378227087u32, 3811616794u32, 291187481u32, 34330861u32, 4032846830u32, 615137029u32, 3603020806u32, 3314634738u32, 939183345u32, 1776939221u32, 2609017814u32, 2295496738u32, 2058945313u32, 2926798794u32, 1545135305u32, 1330124605u32, 3173225534u32, 4084100981u32, 17165430u32, 307568514u32, 3762199681u32, 888469610u32, 3332340585u32, 3587147933u32, 665062302u32, 2042050490u32, 2346497209u32, 2559330125u32, 1793573966u32, 3190661285u32, 1279665062u32, 1595330642u32, 2910671697u32];
const REF_32_EDB88320: [u32; 256] = [0u32, 1996959894u32, 3993919788u32, 2567524794u32, 124634137u32, 1886057615u32, 3915621685u32, 2657392035u32, 249268274u32, 2044508324u32, 3772115230u32, 2547177864u32, 162941995u32, 2125561021u32, 3887607047u32, 2428444049u32, 498536548u32, 1789927666u32, 4089016648u32, 2227061214u32, 450548861u32, 1843258603u32, 4107580753u32, 2211677639u32, 325883990u32, 1684777152u32, 4251122042u32, 2321926636u32, 335633487u32, 1661365465u32, 4195302755u32, 2366115317u32, 997073096u32, 1281953886u32, 3579855332u32, 2724688242u32, 1006888145u32, 1258607687u32, 3524101629u32, 2768942443u32, 901097722u32, 1119000684u32, 3686517206u32, 2898065728u32, 853044451u32, 1172266101u32, 3705015759u32, 2882616665u32, 651767980u32, 1373503546u32, 3369554304u32, 3218104598u32, 565507253u32, 1454621731u32, 3485111705u32, 3099436303u32, 671266974u32, 1594198024u32, 3322730930u32, 2970347812u32, 795835527u32, 1483230225u32, 3244367275u32, 3060149565u32, 1994146192u32, 31158534u32, 2563907772u32, 4023717930u32, 1907459465u32, 112637215u32, 2680153253u32, 3904427059u32, 2013776290u32, 251722036u32, 2517215374u32, 3775830040u32, 2137656763u32, 141376813u32, 2439277719u32, 3865271297u32, 1802195444u32, 476864866u32, 2238001368u32, 4066508878u32, 1812370925u32, 453092731u32, 2181625025u32, 4111451223u32, 1706088902u32, 314042704u32, 2344532202u32, 4240017532u32, 1658658271u32, 366619977u32, 2362670323u32, 4224994405u32, 1303535960u32, 984961486u32, 2747007092u32, 3569037538u32, 1256170817u32, 1037604311u32, 2765210733u32, 3554079995u32, 1131014506u32, 879679996u32, 2909243462u32, 3663771856u32, 1141124467u32, 855842277u32, 2852801631u32, 3708648649u32, 1342533948u32, 654459306u32, 3188396048u32, 3373015174u32, 1466479909u32, 544179635u32, 3110523913u32, 3462522015u32, 1591671054u32, 702138776u32, 2966460450u32, 3352799412u32, 1504918807u32, 783551873u32, 3082640443u32, 3233442989u32, 3988292384u32, 2596254646u32, 62317068u32, 1957810842u32, 3939845945u32, 2647816111u32, 81470997u32, 1943803523u32, 3814918930u32, 2489596804u32, 225274430u32, 2053790376u32, 3826175755u32, 2466906013u32, 167816743u32, 2097651377u32, 4027552580u32, 2265490386u32, 503444072u32, 1762050814u32, 4150417245u32, 2154129355u32, 426522225u32, 1852507879u32, 4275313526u32, 2312317920u32, 282753626u32, 1742555852u32, 4189708143u32, 2394877945u32, 397917763u32, 1622183637u32, 3604390888u32, 2714866558u32, 953729732u32, 1340076626u32, 3518719985u32, 2797360999u32, 1068828381u32, 1219638859u32, 3624741850u32, 2936675148u32, 906185462u32, 1090812512u32, 3747672003u32, 2825379669u32, 829329135u32, 1181335161u32, 3412177804u32, 3160834842u32, 628085408u32, 1382605366u32, 3423369109u32, 3138078467u32, 570562233u32, 1426400815u32, 3317316542u32, 2998733608u32, 733239954u32, 1555261956u32, 3268935591u32, 3050360625u32, 752459403u32, 1541320221u32, 2607071920u32, 3965973030u32, 1969922972u32, 40735498u32, 2617837225u32, 3943577151u32, 1913087877u32, 83908371u32, 2512341634u32, 3803740692u32, 2075208622u32, 213261112u32, 2463272603u32, 3855990285u32, 2094854071u32, 198958881u32, 2262029012u32, 4057260610u32, 1759359992u32, 534414190u32, 2176718541u32, 4139329115u32, 1873836001u32, 414664567u32, 2282248934u32, 4279200368u32, 1711684554u32, 285281116u32, 2405801727u32, 4167216745u32, 1634467795u32, 376229701u32, 2685067896u32, 3608007406u32, 1308918612u32, 956543938u32, 2808555105u32, 3495958263u32, 1231636301u32, 1047427035u32, 2932959818u32, 3654703836u32, 1088359270u32, 936918000u32, 2847714899u32, 3736837829u32, 1202900863u32, 817233897u32, 3183342108u32, 3401237130u32, 1404277552u32, 615818150u32, 3134207493u32, 3453421203u32, 1423857449u32, 601450431u32, 3009837614u32, 3294710456u32, 1567103746u32, 711928724u32, 3020668471u32, 3272380065u32, 1510334235u32, 755167117u32];
const REF_32_D419CC15: [u32; 256] = [0u32, 735957071u32, 1471914142u32, 2087088337u32, 2943828284u32, 2225770867u32, 4174176674u32, 3541119469u32, 4141685331u32, 3707816476u32, 2707864269u32, 2327538306u32, 1504336751u32, 1920437024u32, 236059633u32, 634137534u32, 1166650509u32, 1851030722u32, 305269779u32, 972020828u32, 3942575537u32, 3240312318u32, 3175435567u32, 2526584160u32, 3008673502u32, 2559141521u32, 3840874048u32, 3476211215u32, 472119266u32, 939403181u32, 1268275068u32, 1615169331u32, 2333301018u32, 2697890133u32, 3702061444u32, 4151650763u32, 610539558u32, 263833705u32, 1944041656u32, 1476552951u32, 2110669641u32, 1444123398u32, 712369111u32, 27800472u32, 3535340149u32, 4184134202u32, 2231542507u32, 2933879460u32, 3466261911u32, 3846645208u32, 2569098505u32, 3002893638u32, 1642968235u32, 1244685540u32, 911610933u32, 495699066u32, 944238532u32, 328875915u32, 1878806362u32, 1143054101u32, 2536550136u32, 3169681079u32, 3230338662u32, 3948338729u32, 3189058079u32, 2512976464u32, 3920530049u32, 3262339790u32, 291662627u32, 985643884u32, 1188678589u32, 1828985842u32, 1221079116u32, 1662377987u32, 527667410u32, 883835037u32, 3888083312u32, 3429015871u32, 2953105902u32, 2614690209u32, 4221339282u32, 3493943005u32, 2888246796u32, 2281371203u32, 1424738222u32, 2134251489u32, 55600944u32, 680376191u32, 222403777u32, 647777422u32, 1526348895u32, 1898441744u32, 2721504765u32, 2313883058u32, 4119690595u32, 3729829164u32, 889615109u32, 517710666u32, 1656607643u32, 1231029204u32, 2591109689u32, 2980897398u32, 3452605095u32, 3860284136u32, 3285936470u32, 3892754713u32, 2489371080u32, 3216841095u32, 1823221866u32, 1198651429u32, 991398132u32, 281696443u32, 1888477064u32, 1532104647u32, 657751830u32, 216641369u32, 3757612724u32, 4096085755u32, 2286108202u32, 2745101925u32, 2253571547u32, 2911835540u32, 3521733957u32, 4197758218u32, 690324711u32, 49829032u32, 2124293241u32, 1430516790u32, 3558460437u32, 4291042394u32, 2208459915u32, 2826943684u32, 2070842665u32, 1353932134u32, 752168375u32, 118029816u32, 583325254u32, 152634889u32, 1971287768u32, 1587717783u32, 2377357178u32, 2792245045u32, 3657971684u32, 4057327531u32, 2442158232u32, 3125653719u32, 3324755974u32, 3992326217u32, 1055334820u32, 356184555u32, 1767670074u32, 1115771253u32, 1733130955u32, 1284549252u32, 821484117u32, 455805466u32, 3359259639u32, 3823627192u32, 2676071273u32, 3025947430u32, 1594529039u32, 1960265024u32, 145831313u32, 594339294u32, 4034778163u32, 3684697212u32, 2814801069u32, 2350621922u32, 2849476444u32, 2181717779u32, 4268502978u32, 3585212301u32, 111201888u32, 763174447u32, 1360752382u32, 2059845297u32, 444807554u32, 828303821u32, 1295554844u32, 1726302547u32, 3052697790u32, 2653530353u32, 3796883488u32, 3381790831u32, 3965592529u32, 3347313566u32, 3152380751u32, 2419610368u32, 1126785773u32, 1760866978u32, 345162355u32, 1062146620u32, 1779230218u32, 1104229957u32, 1035421332u32, 376084187u32, 3313215286u32, 4003886969u32, 2462058408u32, 3105740775u32, 2631007321u32, 3071028246u32, 3412745415u32, 3770125448u32, 866565477u32, 410742058u32, 1679629819u32, 1338035636u32, 797264519u32, 72915656u32, 2017389081u32, 1407400534u32, 2163346363u32, 2872040436u32, 3611929381u32, 4237589354u32, 3646443732u32, 4068835483u32, 2397302858u32, 2772312069u32, 1982796264u32, 1576190375u32, 563392886u32, 172581177u32, 3776954128u32, 3401740127u32, 3064209294u32, 2642005953u32, 1315503660u32, 1706372707u32, 433282738u32, 839814909u32, 398632259u32, 1008694540u32, 1081673181u32, 1805964690u32, 3098928255u32, 2473079856u32, 4010689761u32, 3302200494u32, 2761298845u32, 2404107218u32, 4079858435u32, 3639632716u32, 199316129u32, 540836590u32, 1549464127u32, 2005344880u32, 1380649422u32, 2039929217u32, 99658064u32, 774732063u32, 4248586482u32, 3605108925u32, 2861033580u32, 2170173475u32];


impl CRCu32 {
    pub fn crc17can() -> CRCu32 {
        Self::create_crc(0x0001685B, 17, 0x00000000, 0x00000000, false)
    }

    pub fn crc21can() -> CRCu32 {
        Self::create_crc(0x00102899, 21, 0x00000000, 0x00000000, false)
    }

    pub fn crc24() -> CRCu32 {
//        Self::create_crc(0x00864CFB, 24, 0x00B704CE, 0x00000000, false)

        let lookup_table = NO_REF_24_00864CFB;
        Self::create_crc_with_exists_lookup_table(lookup_table, 24, 0x00B704CE, 0x00000000, false)
    }

    pub fn crc24ble() -> CRCu32 {
//        Self::create_crc(0x00DA6000, 24, 0x00555555, 0x00000000, true)

        let lookup_table = REF_24_00DA6000;
        Self::create_crc_with_exists_lookup_table(lookup_table, 24, 0x00555555, 0x00000000, true)
    }

    pub fn crc24flexray_a() -> CRCu32 {
//         Self::create_crc(0x005D6DCB, 24, 0x00FEDCBA, 0x00000000, false)

        let lookup_table = NO_REF_24_005D6DCB;
        Self::create_crc_with_exists_lookup_table(lookup_table, 24, 0x00FEDCBA, 0x00000000, false)
    }

    pub fn crc24flexray_b() -> CRCu32 {
//         Self::create_crc(0x005D6DCB, 24, 0x00ABCDEF, 0x00000000, false)

        let lookup_table = NO_REF_24_005D6DCB;
        Self::create_crc_with_exists_lookup_table(lookup_table, 24, 0x00ABCDEF, 0x00000000, false)
    }

    pub fn crc24lte_a() -> CRCu32 {
//         Self::create_crc(0x00864CFB, 24, 0x00000000, 0x00000000, false)

        let lookup_table = NO_REF_24_00864CFB;
        Self::create_crc_with_exists_lookup_table(lookup_table, 24, 0x00000000, 0x00000000, false)
    }

    pub fn crc24lte_b() -> CRCu32 {
//         Self::create_crc(0x00800063, 24, 0x00000000, 0x00000000, false)

        let lookup_table = NO_REF_24_00800063;
        Self::create_crc_with_exists_lookup_table(lookup_table, 24, 0x00000000, 0x00000000, false)
    }

    pub fn crc24os9() -> CRCu32 {
//         Self::create_crc(0x00800063, 24, 0x00FFFFFF, 0x00FFFFFF, false)

        let lookup_table = NO_REF_24_00800063;
        Self::create_crc_with_exists_lookup_table(lookup_table, 24, 0x00FFFFFF, 0x00FFFFFF, false)
    }

    pub fn crc30cdma() -> CRCu32 {
        Self::create_crc(0x2030B9C7, 30, 0x3FFFFFFF, 0x3FFFFFFF, false)
    }

    pub fn crc32() -> CRCu32 {
//         Self::create_crc(0xEDB88320, 32, 0xFFFFFFFF, 0xFFFFFFFF, true)

        let lookup_table = REF_32_EDB88320;
        Self::create_crc_with_exists_lookup_table(lookup_table, 32, 0xFFFFFFFF, 0xFFFFFFFF, true)
    }

    pub fn crc32mhash() -> CRCu32 {
        let mut crc;

//         crc = Self::create_crc(0x04C11DB7, 32, 0xFFFFFFFF, 0xFFFFFFFF, false);

        let lookup_table = NO_REF_32_04C11DB7;
        crc = Self::create_crc_with_exists_lookup_table(lookup_table, 32, 0xFFFFFFFF, 0xFFFFFFFF, false);

        crc.reorder = true;

        crc
    }

    pub fn crc32bzip2() -> CRCu32 {
//        Self::create_crc(0x04C11DB7, 32, 0xFFFFFFFF, 0xFFFFFFFF, false)

        let lookup_table = NO_REF_32_04C11DB7;
        Self::create_crc_with_exists_lookup_table(lookup_table, 32, 0xFFFFFFFF, 0xFFFFFFFF, false)
    }

    pub fn crc32c() -> CRCu32 {
        // Self::create_crc(0x82F63B78, 32, 0xFFFFFFFF, 0xFFFFFFFF, true)

        let lookup_table = REF_32_82F63B78;
        Self::create_crc_with_exists_lookup_table(lookup_table, 32, 0xFFFFFFFF, 0xFFFFFFFF, true)
    }

    pub fn crc32d() -> CRCu32 {
//         Self::create_crc(0xD419CC15, 32, 0xFFFFFFFF, 0xFFFFFFFF, true)

        let lookup_table = REF_32_D419CC15;
        Self::create_crc_with_exists_lookup_table(lookup_table, 32, 0xFFFFFFFF, 0xFFFFFFFF, true)
    }

    pub fn crc32mpeg2() -> CRCu32 {
//         Self::create_crc(0x04C11DB7, 32, 0xFFFFFFFF, 0x00000000, false)

        let lookup_table = NO_REF_32_04C11DB7;
        Self::create_crc_with_exists_lookup_table(lookup_table, 32, 0xFFFFFFFF, 0x00000000, false)
    }

    pub fn crc32posix() -> CRCu32 {
//         Self::create_crc(0x04C11DB7, 32, 0x00000000, 0xFFFFFFFF, false)

        let lookup_table = NO_REF_32_04C11DB7;
        Self::create_crc_with_exists_lookup_table(lookup_table, 32, 0x00000000, 0xFFFFFFFF, false)
    }

    pub fn crc32q() -> CRCu32 {
//         Self::create_crc(0x814141AB, 32, 0x00000000, 0x00000000, false)

        let lookup_table = NO_REF_32_814141AB;
        Self::create_crc_with_exists_lookup_table(lookup_table, 32, 0x00000000, 0x00000000, false)
    }

    pub fn crc32jamcrc() -> CRCu32 {
//         Self::create_crc(0xEDB88320, 32, 0xFFFFFFFF, 0x00000000, true)

        let lookup_table = REF_32_EDB88320;
        Self::create_crc_with_exists_lookup_table(lookup_table, 32, 0xFFFFFFFF, 0x00000000, true)
    }

    pub fn crc32xfer() -> CRCu32 {
//         Self::create_crc(0x000000AF, 32, 0x00000000, 0x00000000, false)

        let lookup_table = NO_REF_32_000000AF;
        Self::create_crc_with_exists_lookup_table(lookup_table, 32, 0x00000000, 0x00000000, false)
    }
}

#[cfg(all(feature = "development", not(feature = "no_std"), test))]
mod tests {
    use super::CRCu32;

    use std::fmt::Write;

    #[test]
    fn print_lookup_table() {
        let crc = CRCu32::crc24ble();

        let mut s = String::new();

        for n in crc.lookup_table.iter().take(255) {
            s.write_fmt(format_args!("{}u32, ", n)).unwrap();
        }

        s.write_fmt(format_args!("{}u32", crc.lookup_table[255])).unwrap();

        println!("let lookup_table = [{}];", s);
    }
}