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
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
use alloc::vec::Vec;
use alloc::fmt::{self, Formatter, Debug, Display};

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

impl Debug for CRCu16 {
    #[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{:04X}", self.sum), .bits, (.initial, "0x{:04X}", self.initial), (.final_xor, "0x{:04X}", self.final_xor), .reflect, .reorder);
        } else {
            impl_debug_for_struct!(CRCu64, f, self, (.poly, "0x{:04X}", self.poly), (.sum, "0x{:04X}", self.sum), .bits, (.initial, "0x{:04X}", self.initial), (.final_xor, "0x{:04X}", self.final_xor), .reflect, .reorder);
        }
    }
}

impl Display for CRCu16 {
    #[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 CRCu16 {
    /// Create a `CRCu16` instance by providing the length of bits, expression, reflection, an initial value and a final xor value.
    pub fn create_crc(poly: u16, bits: u8, initial: u16, final_xor: u16, reflect: bool) -> CRCu16 {
        debug_assert!(bits <= 16 && 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, [0u16; 256], poly, bits, initial, final_xor, reflect)
        }
    }

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

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

    #[inline]
    fn create(by_table: bool, lookup_table: [u16; 256], mut poly: u16, bits: u8, initial: u16, final_xor: u16, reflect: bool) -> CRCu16 {
        let high_bit = 1 << (bits as u16 - 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);
        }

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

    #[inline]
    fn reflect_function(high_bit: u16, n: u16) -> u16 {
        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: u16) -> u16 {
        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 u16)) 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 `u16` value). You can continue calling `digest` method even after getting a CRC value.
    pub fn get_crc(&self) -> u16 {
        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 u16;

            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 u16;

        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 u16;

        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: u16) -> [u16; 256] {
        let mut lookup_table = [0u16; 256];

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

            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: u16, bits: u8) -> [u16; 256] {
        let mut lookup_table = [0u16; 256];

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

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

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

            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_16_0589: [u16; 256] = [0u16, 1417u16, 2834u16, 3739u16, 5668u16, 5037u16, 7478u16, 6335u16, 11336u16, 10689u16, 10074u16, 8915u16, 14956u16, 16357u16, 12670u16, 13559u16, 22672u16, 23833u16, 21378u16, 22027u16, 20148u16, 19261u16, 17830u16, 16431u16, 29912u16, 29009u16, 32714u16, 31299u16, 25340u16, 26485u16, 27118u16, 27751u16, 45344u16, 46249u16, 47666u16, 49083u16, 42756u16, 41613u16, 44054u16, 43423u16, 40296u16, 39137u16, 38522u16, 37875u16, 35660u16, 36549u16, 32862u16, 34263u16, 59824u16, 60473u16, 58018u16, 59179u16, 65428u16, 64029u16, 62598u16, 61711u16, 50680u16, 49265u16, 52970u16, 52067u16, 54236u16, 54869u16, 55502u16, 56647u16, 26569u16, 25152u16, 27867u16, 26962u16, 29165u16, 29796u16, 31487u16, 32630u16, 19329u16, 19976u16, 16531u16, 17690u16, 23973u16, 22572u16, 22199u16, 21310u16, 16217u16, 15056u16, 13387u16, 12738u16, 10621u16, 11508u16, 8815u16, 10214u16, 4881u16, 5784u16, 6147u16, 7562u16, 1333u16, 188u16, 3623u16, 2990u16, 55017u16, 54112u16, 56827u16, 55410u16, 49357u16, 50500u16, 52191u16, 52822u16, 64161u16, 65320u16, 61875u16, 62522u16, 60549u16, 59660u16, 59287u16, 57886u16, 36473u16, 35824u16, 34155u16, 32994u16, 39005u16, 40404u16, 37711u16, 38598u16, 41521u16, 42936u16, 43299u16, 44202u16, 46101u16, 45468u16, 48903u16, 47758u16, 53138u16, 51739u16, 50304u16, 49417u16, 55734u16, 56383u16, 53924u16, 55085u16, 58330u16, 58963u16, 59592u16, 60737u16, 62974u16, 61559u16, 65260u16, 64357u16, 38658u16, 37515u16, 39952u16, 39321u16, 33062u16, 33967u16, 35380u16, 36797u16, 47946u16, 48835u16, 45144u16, 46545u16, 44398u16, 43239u16, 42620u16, 41973u16, 32434u16, 31547u16, 30112u16, 28713u16, 26774u16, 27935u16, 25476u16, 26125u16, 21242u16, 22387u16, 23016u16, 23649u16, 17630u16, 16727u16, 20428u16, 19013u16, 9762u16, 9131u16, 11568u16, 10425u16, 12294u16, 13711u16, 15124u16, 16029u16, 2666u16, 4067u16, 376u16, 1265u16, 7246u16, 6599u16, 5980u16, 4821u16, 43099u16, 44498u16, 41801u16, 42688u16, 48767u16, 48118u16, 46445u16, 45284u16, 33811u16, 33178u16, 36609u16, 35464u16, 37431u16, 38846u16, 39205u16, 40108u16, 61643u16, 62786u16, 64473u16, 65104u16, 59119u16, 58214u16, 60925u16, 59508u16, 56451u16, 55562u16, 55185u16, 53784u16, 51879u16, 53038u16, 49589u16, 50236u16, 6523u16, 7410u16, 4713u16, 6112u16, 3935u16, 2774u16, 1101u16, 452u16, 13619u16, 12474u16, 15905u16, 15272u16, 8983u16, 9886u16, 10245u16, 11660u16, 16875u16, 17506u16, 19193u16, 20336u16, 22479u16, 21062u16, 23773u16, 22868u16, 28067u16, 26666u16, 26289u16, 25400u16, 31623u16, 32270u16, 28821u16, 29980u16];
const NO_REF_16_1021: [u16; 256] = [0u16, 4129u16, 8258u16, 12387u16, 16516u16, 20645u16, 24774u16, 28903u16, 33032u16, 37161u16, 41290u16, 45419u16, 49548u16, 53677u16, 57806u16, 61935u16, 4657u16, 528u16, 12915u16, 8786u16, 21173u16, 17044u16, 29431u16, 25302u16, 37689u16, 33560u16, 45947u16, 41818u16, 54205u16, 50076u16, 62463u16, 58334u16, 9314u16, 13379u16, 1056u16, 5121u16, 25830u16, 29895u16, 17572u16, 21637u16, 42346u16, 46411u16, 34088u16, 38153u16, 58862u16, 62927u16, 50604u16, 54669u16, 13907u16, 9842u16, 5649u16, 1584u16, 30423u16, 26358u16, 22165u16, 18100u16, 46939u16, 42874u16, 38681u16, 34616u16, 63455u16, 59390u16, 55197u16, 51132u16, 18628u16, 22757u16, 26758u16, 30887u16, 2112u16, 6241u16, 10242u16, 14371u16, 51660u16, 55789u16, 59790u16, 63919u16, 35144u16, 39273u16, 43274u16, 47403u16, 23285u16, 19156u16, 31415u16, 27286u16, 6769u16, 2640u16, 14899u16, 10770u16, 56317u16, 52188u16, 64447u16, 60318u16, 39801u16, 35672u16, 47931u16, 43802u16, 27814u16, 31879u16, 19684u16, 23749u16, 11298u16, 15363u16, 3168u16, 7233u16, 60846u16, 64911u16, 52716u16, 56781u16, 44330u16, 48395u16, 36200u16, 40265u16, 32407u16, 28342u16, 24277u16, 20212u16, 15891u16, 11826u16, 7761u16, 3696u16, 65439u16, 61374u16, 57309u16, 53244u16, 48923u16, 44858u16, 40793u16, 36728u16, 37256u16, 33193u16, 45514u16, 41451u16, 53516u16, 49453u16, 61774u16, 57711u16, 4224u16, 161u16, 12482u16, 8419u16, 20484u16, 16421u16, 28742u16, 24679u16, 33721u16, 37784u16, 41979u16, 46042u16, 49981u16, 54044u16, 58239u16, 62302u16, 689u16, 4752u16, 8947u16, 13010u16, 16949u16, 21012u16, 25207u16, 29270u16, 46570u16, 42443u16, 38312u16, 34185u16, 62830u16, 58703u16, 54572u16, 50445u16, 13538u16, 9411u16, 5280u16, 1153u16, 29798u16, 25671u16, 21540u16, 17413u16, 42971u16, 47098u16, 34713u16, 38840u16, 59231u16, 63358u16, 50973u16, 55100u16, 9939u16, 14066u16, 1681u16, 5808u16, 26199u16, 30326u16, 17941u16, 22068u16, 55628u16, 51565u16, 63758u16, 59695u16, 39368u16, 35305u16, 47498u16, 43435u16, 22596u16, 18533u16, 30726u16, 26663u16, 6336u16, 2273u16, 14466u16, 10403u16, 52093u16, 56156u16, 60223u16, 64286u16, 35833u16, 39896u16, 43963u16, 48026u16, 19061u16, 23124u16, 27191u16, 31254u16, 2801u16, 6864u16, 10931u16, 14994u16, 64814u16, 60687u16, 56684u16, 52557u16, 48554u16, 44427u16, 40424u16, 36297u16, 31782u16, 27655u16, 23652u16, 19525u16, 15522u16, 11395u16, 7392u16, 3265u16, 61215u16, 65342u16, 53085u16, 57212u16, 44955u16, 49082u16, 36825u16, 40952u16, 28183u16, 32310u16, 20053u16, 24180u16, 11923u16, 16050u16, 3793u16, 7920u16];
const NO_REF_16_3D65: [u16; 256] = [0u16, 15717u16, 31434u16, 18351u16, 62868u16, 51441u16, 36702u16, 45627u16, 54861u16, 60200u16, 44167u16, 37346u16, 9177u16, 7868u16, 22803u16, 25718u16, 37375u16, 44186u16, 60213u16, 54864u16, 25707u16, 22798u16, 7841u16, 9156u16, 18354u16, 31447u16, 15736u16, 29u16, 45606u16, 36675u16, 51436u16, 62857u16, 7835u16, 9214u16, 25681u16, 22836u16, 60175u16, 54890u16, 37317u16, 44192u16, 51414u16, 62899u16, 45596u16, 36729u16, 15682u16, 39u16, 18312u16, 31469u16, 36708u16, 45569u16, 62894u16, 51403u16, 31472u16, 18325u16, 58u16, 15711u16, 22825u16, 25676u16, 9187u16, 7814u16, 44221u16, 37336u16, 54903u16, 60178u16, 15670u16, 83u16, 18428u16, 31385u16, 51362u16, 62919u16, 45672u16, 36621u16, 60283u16, 54814u16, 37297u16, 44244u16, 7919u16, 9098u16, 25637u16, 22848u16, 44233u16, 37292u16, 54787u16, 60262u16, 22877u16, 25656u16, 9111u16, 7922u16, 31364u16, 18401u16, 78u16, 15659u16, 36624u16, 45685u16, 62938u16, 51391u16, 9133u16, 7880u16, 22887u16, 25602u16, 54841u16, 60252u16, 44275u16, 37270u16, 62944u16, 51333u16, 36650u16, 45647u16, 116u16, 15633u16, 31422u16, 18395u16, 45650u16, 36663u16, 51352u16, 62973u16, 18374u16, 31395u16, 15628u16, 105u16, 25631u16, 22906u16, 7893u16, 9136u16, 37259u16, 44270u16, 60225u16, 54820u16, 31340u16, 18185u16, 166u16, 15811u16, 36856u16, 45725u16, 62770u16, 51287u16, 44065u16, 37188u16, 55019u16, 60302u16, 22965u16, 25808u16, 9087u16, 7706u16, 60307u16, 55030u16, 37209u16, 44092u16, 7687u16, 9058u16, 25805u16, 22952u16, 15838u16, 187u16, 18196u16, 31345u16, 51274u16, 62767u16, 45696u16, 36837u16, 25847u16, 22930u16, 7741u16, 9048u16, 37219u16, 44038u16, 60329u16, 54988u16, 45754u16, 36831u16, 51312u16, 62741u16, 18222u16, 31307u16, 15844u16, 129u16, 62728u16, 51309u16, 36802u16, 45735u16, 156u16, 15865u16, 31318u16, 18227u16, 9029u16, 7712u16, 22927u16, 25834u16, 54993u16, 60340u16, 44059u16, 37246u16, 18266u16, 31295u16, 15760u16, 245u16, 45774u16, 36779u16, 51204u16, 62817u16, 37143u16, 44146u16, 60381u16, 54968u16, 25731u16, 23014u16, 7753u16, 9004u16, 54949u16, 60352u16, 44143u16, 37130u16, 9009u16, 7764u16, 23035u16, 25758u16, 232u16, 15757u16, 31266u16, 18247u16, 62844u16, 51225u16, 36790u16, 45779u16, 22977u16, 25764u16, 8971u16, 7790u16, 44117u16, 37168u16, 54943u16, 60410u16, 36748u16, 45801u16, 62790u16, 51235u16, 31256u16, 18301u16, 210u16, 15799u16, 51262u16, 62811u16, 45812u16, 36753u16, 15786u16, 207u16, 18272u16, 31237u16, 7795u16, 8982u16, 25785u16, 23004u16, 60391u16, 54914u16, 37165u16, 44104u16];
const NO_REF_16_8005: [u16; 256] = [0u16, 32773u16, 32783u16, 10u16, 32795u16, 30u16, 20u16, 32785u16, 32819u16, 54u16, 60u16, 32825u16, 40u16, 32813u16, 32807u16, 34u16, 32867u16, 102u16, 108u16, 32873u16, 120u16, 32893u16, 32887u16, 114u16, 80u16, 32853u16, 32863u16, 90u16, 32843u16, 78u16, 68u16, 32833u16, 32963u16, 198u16, 204u16, 32969u16, 216u16, 32989u16, 32983u16, 210u16, 240u16, 33013u16, 33023u16, 250u16, 33003u16, 238u16, 228u16, 32993u16, 160u16, 32933u16, 32943u16, 170u16, 32955u16, 190u16, 180u16, 32945u16, 32915u16, 150u16, 156u16, 32921u16, 136u16, 32909u16, 32903u16, 130u16, 33155u16, 390u16, 396u16, 33161u16, 408u16, 33181u16, 33175u16, 402u16, 432u16, 33205u16, 33215u16, 442u16, 33195u16, 430u16, 420u16, 33185u16, 480u16, 33253u16, 33263u16, 490u16, 33275u16, 510u16, 500u16, 33265u16, 33235u16, 470u16, 476u16, 33241u16, 456u16, 33229u16, 33223u16, 450u16, 320u16, 33093u16, 33103u16, 330u16, 33115u16, 350u16, 340u16, 33105u16, 33139u16, 374u16, 380u16, 33145u16, 360u16, 33133u16, 33127u16, 354u16, 33059u16, 294u16, 300u16, 33065u16, 312u16, 33085u16, 33079u16, 306u16, 272u16, 33045u16, 33055u16, 282u16, 33035u16, 270u16, 260u16, 33025u16, 33539u16, 774u16, 780u16, 33545u16, 792u16, 33565u16, 33559u16, 786u16, 816u16, 33589u16, 33599u16, 826u16, 33579u16, 814u16, 804u16, 33569u16, 864u16, 33637u16, 33647u16, 874u16, 33659u16, 894u16, 884u16, 33649u16, 33619u16, 854u16, 860u16, 33625u16, 840u16, 33613u16, 33607u16, 834u16, 960u16, 33733u16, 33743u16, 970u16, 33755u16, 990u16, 980u16, 33745u16, 33779u16, 1014u16, 1020u16, 33785u16, 1000u16, 33773u16, 33767u16, 994u16, 33699u16, 934u16, 940u16, 33705u16, 952u16, 33725u16, 33719u16, 946u16, 912u16, 33685u16, 33695u16, 922u16, 33675u16, 910u16, 900u16, 33665u16, 640u16, 33413u16, 33423u16, 650u16, 33435u16, 670u16, 660u16, 33425u16, 33459u16, 694u16, 700u16, 33465u16, 680u16, 33453u16, 33447u16, 674u16, 33507u16, 742u16, 748u16, 33513u16, 760u16, 33533u16, 33527u16, 754u16, 720u16, 33493u16, 33503u16, 730u16, 33483u16, 718u16, 708u16, 33473u16, 33347u16, 582u16, 588u16, 33353u16, 600u16, 33373u16, 33367u16, 594u16, 624u16, 33397u16, 33407u16, 634u16, 33387u16, 622u16, 612u16, 33377u16, 544u16, 33317u16, 33327u16, 554u16, 33339u16, 574u16, 564u16, 33329u16, 33299u16, 534u16, 540u16, 33305u16, 520u16, 33293u16, 33287u16, 514u16];
const NO_REF_16_8BB7: [u16; 256] = [0u16, 35767u16, 40153u16, 5998u16, 45573u16, 14770u16, 11996u16, 42347u16, 61373u16, 25610u16, 29540u16, 63699u16, 23992u16, 54799u16, 49505u16, 19158u16, 21709u16, 57210u16, 51220u16, 17315u16, 59080u16, 28031u16, 31249u16, 61862u16, 47984u16, 12487u16, 10153u16, 44062u16, 2421u16, 33474u16, 38316u16, 7707u16, 43418u16, 8749u16, 13635u16, 48884u16, 7071u16, 36904u16, 34630u16, 3313u16, 17959u16, 52624u16, 56062u16, 20809u16, 62498u16, 32661u16, 26875u16, 58188u16, 64855u16, 30432u16, 24974u16, 59961u16, 20306u16, 50405u16, 54155u16, 22588u16, 4842u16, 39261u16, 36403u16, 1412u16, 41199u16, 11096u16, 15414u16, 46977u16, 55427u16, 21300u16, 17498u16, 53229u16, 27270u16, 57649u16, 63071u16, 32232u16, 14142u16, 48265u16, 44007u16, 8272u16, 34107u16, 3724u16, 6626u16, 37461u16, 35918u16, 2041u16, 4247u16, 39712u16, 15947u16, 46588u16, 41618u16, 10533u16, 25587u16, 59460u16, 65322u16, 29853u16, 53750u16, 23105u16, 19759u16, 50840u16, 28953u16, 64174u16, 60864u16, 26231u16, 49948u16, 18603u16, 24517u16, 54386u16, 40612u16, 5395u16, 637u16, 35274u16, 11425u16, 42774u16, 45176u16, 15311u16, 9684u16, 44643u16, 47373u16, 12986u16, 38865u16, 7270u16, 2824u16, 32959u16, 51817u16, 16862u16, 22192u16, 56583u16, 30828u16, 62427u16, 58549u16, 28418u16, 15025u16, 45318u16, 42600u16, 11743u16, 34996u16, 771u16, 5229u16, 40922u16, 54540u16, 24251u16, 18901u16, 49762u16, 26377u16, 60606u16, 64464u16, 28775u16, 28284u16, 58827u16, 62117u16, 30994u16, 56441u16, 22478u16, 16544u16, 51991u16, 33217u16, 2678u16, 7448u16, 38575u16, 13252u16, 47219u16, 44829u16, 9386u16, 37675u16, 6300u16, 4082u16, 33861u16, 8494u16, 43673u16, 48631u16, 13888u16, 31894u16, 63265u16, 57423u16, 27640u16, 52883u16, 17700u16, 21066u16, 55805u16, 51174u16, 19537u16, 23359u16, 53384u16, 30179u16, 65108u16, 59706u16, 25229u16, 10331u16, 41964u16, 46210u16, 16181u16, 39518u16, 4585u16, 1671u16, 36144u16, 57906u16, 27013u16, 32491u16, 62812u16, 20535u16, 56192u16, 52462u16, 18265u16, 3471u16, 34360u16, 37206u16, 6881u16, 49034u16, 13373u16, 9043u16, 43236u16, 46847u16, 15688u16, 10790u16, 41361u16, 1274u16, 36685u16, 38947u16, 5012u16, 22850u16, 54005u16, 50587u16, 20012u16, 60231u16, 24816u16, 30622u16, 64553u16, 19368u16, 49183u16, 55153u16, 23750u16, 63917u16, 29210u16, 25972u16, 61123u16, 42005u16, 12194u16, 14540u16, 45947u16, 5648u16, 40359u16, 35529u16, 382u16, 8037u16, 38098u16, 33724u16, 2059u16, 44384u16, 9943u16, 12729u16, 47630u16, 61656u16, 31599u16, 27649u16, 59318u16, 17117u16, 51562u16, 56836u16, 21939u16];
const NO_REF_16_C867: [u16; 256] = [0u16, 51303u16, 22697u16, 37070u16, 45394u16, 31029u16, 59899u16, 8604u16, 43715u16, 25252u16, 62058u16, 14861u16, 7057u16, 54262u16, 17208u16, 35679u16, 40417u16, 21894u16, 50504u16, 3375u16, 11443u16, 58580u16, 29722u16, 48253u16, 14114u16, 65349u16, 28555u16, 42988u16, 34416u16, 19991u16, 57049u16, 5822u16, 62373u16, 15298u16, 43788u16, 25451u16, 17143u16, 35472u16, 6750u16, 53817u16, 22886u16, 37121u16, 463u16, 51624u16, 59444u16, 8275u16, 45213u16, 30970u16, 28228u16, 42531u16, 14061u16, 65162u16, 57110u16, 6001u16, 34751u16, 20440u16, 50311u16, 3296u16, 39982u16, 21577u16, 30165u16, 48562u16, 11644u16, 58651u16, 12077u16, 59210u16, 30596u16, 49123u16, 40575u16, 22040u16, 50902u16, 3761u16, 34286u16, 19849u16, 56647u16, 5408u16, 13500u16, 64731u16, 27669u16, 42098u16, 45772u16, 31403u16, 60005u16, 8706u16, 926u16, 52217u16, 23351u16, 37712u16, 6159u16, 53352u16, 16550u16, 35009u16, 43357u16, 24890u16, 61940u16, 14739u16, 56456u16, 5359u16, 33825u16, 19526u16, 28122u16, 42429u16, 13683u16, 64788u16, 30283u16, 48684u16, 12002u16, 59013u16, 50969u16, 3966u16, 40880u16, 22487u16, 16745u16, 35086u16, 6592u16, 53671u16, 61499u16, 14428u16, 43154u16, 24821u16, 60330u16, 9165u16, 45827u16, 31588u16, 23288u16, 37535u16, 593u16, 51766u16, 24154u16, 38461u16, 1779u16, 52884u16, 61192u16, 10095u16, 47009u16, 32710u16, 62617u16, 15614u16, 44080u16, 25687u16, 17867u16, 36268u16, 7522u16, 54533u16, 50107u16, 3036u16, 39698u16, 21365u16, 29417u16, 47758u16, 10816u16, 57895u16, 27000u16, 41247u16, 12753u16, 63926u16, 55338u16, 4173u16, 32899u16, 18660u16, 44543u16, 26008u16, 62806u16, 15665u16, 7341u16, 54474u16, 17412u16, 35939u16, 1852u16, 53083u16, 24469u16, 38898u16, 46702u16, 32265u16, 61127u16, 9888u16, 12318u16, 63609u16, 26807u16, 41168u16, 33100u16, 18731u16, 55781u16, 4482u16, 39645u16, 21178u16, 49780u16, 2579u16, 11151u16, 58344u16, 29478u16, 47937u16, 29047u16, 47376u16, 10718u16, 57785u16, 49189u16, 2114u16, 39052u16, 20715u16, 56244u16, 5075u16, 33565u16, 19322u16, 27366u16, 41601u16, 12879u16, 64040u16, 60566u16, 9457u16, 46143u16, 31832u16, 24004u16, 38307u16, 1389u16, 52490u16, 18005u16, 36402u16, 7932u16, 54939u16, 63239u16, 16224u16, 44974u16, 26569u16, 33490u16, 19125u16, 55931u16, 4636u16, 13184u16, 64487u16, 27433u16, 41806u16, 10257u16, 57462u16, 28856u16, 47327u16, 39235u16, 20772u16, 49642u16, 2445u16, 7987u16, 55124u16, 18330u16, 36861u16, 44641u16, 26118u16, 63176u16, 16047u16, 46576u16, 32151u16, 60761u16, 9534u16, 1186u16, 52421u16, 23563u16, 37996u16];

const REF_16_8408: [u16; 256] = [0u16, 4489u16, 8978u16, 12955u16, 17956u16, 22445u16, 25910u16, 29887u16, 35912u16, 40385u16, 44890u16, 48851u16, 51820u16, 56293u16, 59774u16, 63735u16, 4225u16, 264u16, 13203u16, 8730u16, 22181u16, 18220u16, 30135u16, 25662u16, 40137u16, 36160u16, 49115u16, 44626u16, 56045u16, 52068u16, 63999u16, 59510u16, 8450u16, 12427u16, 528u16, 5017u16, 26406u16, 30383u16, 17460u16, 21949u16, 44362u16, 48323u16, 36440u16, 40913u16, 60270u16, 64231u16, 51324u16, 55797u16, 12675u16, 8202u16, 4753u16, 792u16, 30631u16, 26158u16, 21685u16, 17724u16, 48587u16, 44098u16, 40665u16, 36688u16, 64495u16, 60006u16, 55549u16, 51572u16, 16900u16, 21389u16, 24854u16, 28831u16, 1056u16, 5545u16, 10034u16, 14011u16, 52812u16, 57285u16, 60766u16, 64727u16, 34920u16, 39393u16, 43898u16, 47859u16, 21125u16, 17164u16, 29079u16, 24606u16, 5281u16, 1320u16, 14259u16, 9786u16, 57037u16, 53060u16, 64991u16, 60502u16, 39145u16, 35168u16, 48123u16, 43634u16, 25350u16, 29327u16, 16404u16, 20893u16, 9506u16, 13483u16, 1584u16, 6073u16, 61262u16, 65223u16, 52316u16, 56789u16, 43370u16, 47331u16, 35448u16, 39921u16, 29575u16, 25102u16, 20629u16, 16668u16, 13731u16, 9258u16, 5809u16, 1848u16, 65487u16, 60998u16, 56541u16, 52564u16, 47595u16, 43106u16, 39673u16, 35696u16, 33800u16, 38273u16, 42778u16, 46739u16, 49708u16, 54181u16, 57662u16, 61623u16, 2112u16, 6601u16, 11090u16, 15067u16, 20068u16, 24557u16, 28022u16, 31999u16, 38025u16, 34048u16, 47003u16, 42514u16, 53933u16, 49956u16, 61887u16, 57398u16, 6337u16, 2376u16, 15315u16, 10842u16, 24293u16, 20332u16, 32247u16, 27774u16, 42250u16, 46211u16, 34328u16, 38801u16, 58158u16, 62119u16, 49212u16, 53685u16, 10562u16, 14539u16, 2640u16, 7129u16, 28518u16, 32495u16, 19572u16, 24061u16, 46475u16, 41986u16, 38553u16, 34576u16, 62383u16, 57894u16, 53437u16, 49460u16, 14787u16, 10314u16, 6865u16, 2904u16, 32743u16, 28270u16, 23797u16, 19836u16, 50700u16, 55173u16, 58654u16, 62615u16, 32808u16, 37281u16, 41786u16, 45747u16, 19012u16, 23501u16, 26966u16, 30943u16, 3168u16, 7657u16, 12146u16, 16123u16, 54925u16, 50948u16, 62879u16, 58390u16, 37033u16, 33056u16, 46011u16, 41522u16, 23237u16, 19276u16, 31191u16, 26718u16, 7393u16, 3432u16, 16371u16, 11898u16, 59150u16, 63111u16, 50204u16, 54677u16, 41258u16, 45219u16, 33336u16, 37809u16, 27462u16, 31439u16, 18516u16, 23005u16, 11618u16, 15595u16, 3696u16, 8185u16, 63375u16, 58886u16, 54429u16, 50452u16, 45483u16, 40994u16, 37561u16, 33584u16, 31687u16, 27214u16, 22741u16, 18780u16, 15843u16, 11370u16, 7921u16, 3960u16];
const REF_16_A001: [u16; 256] = [0u16, 49345u16, 49537u16, 320u16, 49921u16, 960u16, 640u16, 49729u16, 50689u16, 1728u16, 1920u16, 51009u16, 1280u16, 50625u16, 50305u16, 1088u16, 52225u16, 3264u16, 3456u16, 52545u16, 3840u16, 53185u16, 52865u16, 3648u16, 2560u16, 51905u16, 52097u16, 2880u16, 51457u16, 2496u16, 2176u16, 51265u16, 55297u16, 6336u16, 6528u16, 55617u16, 6912u16, 56257u16, 55937u16, 6720u16, 7680u16, 57025u16, 57217u16, 8000u16, 56577u16, 7616u16, 7296u16, 56385u16, 5120u16, 54465u16, 54657u16, 5440u16, 55041u16, 6080u16, 5760u16, 54849u16, 53761u16, 4800u16, 4992u16, 54081u16, 4352u16, 53697u16, 53377u16, 4160u16, 61441u16, 12480u16, 12672u16, 61761u16, 13056u16, 62401u16, 62081u16, 12864u16, 13824u16, 63169u16, 63361u16, 14144u16, 62721u16, 13760u16, 13440u16, 62529u16, 15360u16, 64705u16, 64897u16, 15680u16, 65281u16, 16320u16, 16000u16, 65089u16, 64001u16, 15040u16, 15232u16, 64321u16, 14592u16, 63937u16, 63617u16, 14400u16, 10240u16, 59585u16, 59777u16, 10560u16, 60161u16, 11200u16, 10880u16, 59969u16, 60929u16, 11968u16, 12160u16, 61249u16, 11520u16, 60865u16, 60545u16, 11328u16, 58369u16, 9408u16, 9600u16, 58689u16, 9984u16, 59329u16, 59009u16, 9792u16, 8704u16, 58049u16, 58241u16, 9024u16, 57601u16, 8640u16, 8320u16, 57409u16, 40961u16, 24768u16, 24960u16, 41281u16, 25344u16, 41921u16, 41601u16, 25152u16, 26112u16, 42689u16, 42881u16, 26432u16, 42241u16, 26048u16, 25728u16, 42049u16, 27648u16, 44225u16, 44417u16, 27968u16, 44801u16, 28608u16, 28288u16, 44609u16, 43521u16, 27328u16, 27520u16, 43841u16, 26880u16, 43457u16, 43137u16, 26688u16, 30720u16, 47297u16, 47489u16, 31040u16, 47873u16, 31680u16, 31360u16, 47681u16, 48641u16, 32448u16, 32640u16, 48961u16, 32000u16, 48577u16, 48257u16, 31808u16, 46081u16, 29888u16, 30080u16, 46401u16, 30464u16, 47041u16, 46721u16, 30272u16, 29184u16, 45761u16, 45953u16, 29504u16, 45313u16, 29120u16, 28800u16, 45121u16, 20480u16, 37057u16, 37249u16, 20800u16, 37633u16, 21440u16, 21120u16, 37441u16, 38401u16, 22208u16, 22400u16, 38721u16, 21760u16, 38337u16, 38017u16, 21568u16, 39937u16, 23744u16, 23936u16, 40257u16, 24320u16, 40897u16, 40577u16, 24128u16, 23040u16, 39617u16, 39809u16, 23360u16, 39169u16, 22976u16, 22656u16, 38977u16, 34817u16, 18624u16, 18816u16, 35137u16, 19200u16, 35777u16, 35457u16, 19008u16, 19968u16, 36545u16, 36737u16, 20288u16, 36097u16, 19904u16, 19584u16, 35905u16, 17408u16, 33985u16, 34177u16, 17728u16, 34561u16, 18368u16, 18048u16, 34369u16, 33281u16, 17088u16, 17280u16, 33601u16, 16640u16, 33217u16, 32897u16, 16448u16];
const REF_16_A097: [u16; 256] = [0u16, 41111u16, 57785u16, 16686u16, 25573u16, 50034u16, 33372u16, 8907u16, 51146u16, 26461u16, 9843u16, 34532u16, 42031u16, 1208u16, 17814u16, 58625u16, 12035u16, 36756u16, 52922u16, 28205u16, 19686u16, 60529u16, 44383u16, 3528u16, 59593u16, 18526u16, 2416u16, 43495u16, 35628u16, 11195u16, 27285u16, 51714u16, 24070u16, 65169u16, 49087u16, 7976u16, 15843u16, 40308u16, 56410u16, 31949u16, 39372u16, 14683u16, 30837u16, 55522u16, 64041u16, 23230u16, 7056u16, 47879u16, 28933u16, 53650u16, 37052u16, 12331u16, 4832u16, 45687u16, 62297u16, 21454u16, 46799u16, 5720u16, 22390u16, 63457u16, 54570u16, 30141u16, 13459u16, 37892u16, 48140u16, 7323u16, 23989u16, 64802u16, 57321u16, 32638u16, 15952u16, 40647u16, 31686u16, 56145u16, 39551u16, 15080u16, 6179u16, 47284u16, 63898u16, 22797u16, 37647u16, 13208u16, 29366u16, 53793u16, 61674u16, 20605u16, 4435u16, 45508u16, 21701u16, 62546u16, 46460u16, 5611u16, 14112u16, 38839u16, 54937u16, 30222u16, 57866u16, 17053u16, 947u16, 41764u16, 33263u16, 8568u16, 24662u16, 49345u16, 9664u16, 34135u16, 50297u16, 25838u16, 17957u16, 59058u16, 42908u16, 1803u16, 52489u16, 28062u16, 11440u16, 35879u16, 44780u16, 3707u16, 20309u16, 61378u16, 2755u16, 43604u16, 60282u16, 19437u16, 26918u16, 51633u16, 34975u16, 10248u16, 55439u16, 30744u16, 14646u16, 39329u16, 47978u16, 7165u16, 23251u16, 64068u16, 8005u16, 49106u16, 65276u16, 24171u16, 31904u16, 56375u16, 40217u16, 15758u16, 63372u16, 22299u16, 5685u16, 46754u16, 37993u16, 13566u16, 30160u16, 54599u16, 12358u16, 37073u16, 53759u16, 29032u16, 21411u16, 62260u16, 45594u16, 4749u16, 34441u16, 9758u16, 26416u16, 51111u16, 58732u16, 17915u16, 1237u16, 42050u16, 16707u16, 57812u16, 41210u16, 109u16, 8870u16, 33329u16, 49951u16, 25480u16, 43402u16, 2333u16, 18483u16, 59556u16, 51823u16, 27384u16, 11222u16, 35649u16, 28224u16, 52951u16, 36857u16, 12142u16, 3493u16, 44338u16, 60444u16, 19595u16, 25731u16, 50196u16, 34106u16, 9645u16, 1894u16, 42993u16, 59103u16, 17992u16, 41801u16, 990u16, 17136u16, 57959u16, 49324u16, 24635u16, 8469u16, 33154u16, 19328u16, 60183u16, 43577u16, 2734u16, 10341u16, 35058u16, 51676u16, 26955u16, 35914u16, 11485u16, 28147u16, 52580u16, 61359u16, 20280u16, 3606u16, 44673u16, 14981u16, 39442u16, 56124u16, 31659u16, 22880u16, 63991u16, 47321u16, 6222u16, 64847u16, 24024u16, 7414u16, 48225u16, 40618u16, 15933u16, 32531u16, 57220u16, 5510u16, 46353u16, 62527u16, 21672u16, 30307u16, 55028u16, 38874u16, 14157u16, 53836u16, 29403u16, 13301u16, 37730u16, 45481u16, 4414u16, 20496u16, 61575u16];
const REF_16_A6BC: [u16; 256] = [0u16, 13918u16, 27836u16, 23266u16, 55672u16, 61222u16, 46532u16, 33690u16, 65417u16, 51671u16, 37685u16, 42347u16, 9969u16, 4271u16, 19021u16, 31763u16, 45675u16, 33845u16, 57047u16, 59529u16, 27411u16, 23885u16, 1967u16, 12785u16, 19938u16, 31676u16, 8542u16, 5888u16, 38042u16, 41668u16, 63526u16, 52856u16, 10671u16, 8177u16, 17683u16, 29517u16, 61655u16, 50825u16, 40043u16, 43573u16, 54822u16, 57464u16, 47770u16, 36036u16, 3934u16, 14592u16, 25570u16, 21948u16, 39876u16, 44442u16, 63352u16, 49446u16, 17084u16, 29922u16, 11776u16, 6238u16, 25677u16, 21011u16, 2289u16, 16047u16, 48437u16, 35691u16, 53641u16, 59351u16, 21342u16, 25856u16, 16354u16, 2492u16, 35366u16, 48248u16, 59034u16, 53444u16, 44247u16, 39561u16, 49259u16, 63029u16, 30127u16, 17393u16, 6419u16, 12109u16, 57653u16, 55147u16, 36233u16, 48087u16, 14413u16, 3603u16, 21745u16, 25263u16, 7868u16, 10466u16, 29184u16, 17502u16, 51140u16, 61850u16, 43896u16, 40230u16, 31473u16, 19631u16, 5709u16, 8211u16, 41865u16, 38359u16, 53045u16, 63851u16, 34168u16, 45862u16, 59844u16, 57242u16, 23552u16, 27230u16, 12476u16, 1762u16, 51354u16, 65220u16, 42022u16, 37496u16, 4578u16, 10172u16, 32094u16, 19200u16, 14099u16, 333u16, 23471u16, 28145u16, 61035u16, 55349u16, 33495u16, 46217u16, 42684u16, 37090u16, 51712u16, 64606u16, 32708u16, 18842u16, 4984u16, 9510u16, 22837u16, 28523u16, 13705u16, 983u16, 32845u16, 46611u16, 60657u16, 55983u16, 5335u16, 8841u16, 30827u16, 20021u16, 52655u16, 64497u16, 41235u16, 38733u16, 60254u16, 56576u16, 34786u16, 45500u16, 12838u16, 1144u16, 24218u16, 26820u16, 36627u16, 47437u16, 58287u16, 54769u16, 22123u16, 24629u16, 15063u16, 3209u16, 28826u16, 18116u16, 7206u16, 10872u16, 43490u16, 40892u16, 50526u16, 62208u16, 15736u16, 2854u16, 20932u16, 26522u16, 58368u16, 53854u16, 35004u16, 48866u16, 49905u16, 62639u16, 44621u16, 38931u16, 7049u16, 11735u16, 30517u16, 16747u16, 62946u16, 50108u16, 39262u16, 44800u16, 11418u16, 6852u16, 16422u16, 30328u16, 2667u16, 15413u16, 26327u16, 20617u16, 54035u16, 58701u16, 49071u16, 35313u16, 18313u16, 29143u16, 11061u16, 7531u16, 40689u16, 43183u16, 62029u16, 50195u16, 47104u16, 36446u16, 54460u16, 58082u16, 24952u16, 22310u16, 3524u16, 15258u16, 56397u16, 59923u16, 45297u16, 34479u16, 1333u16, 13163u16, 27017u16, 24535u16, 9156u16, 5530u16, 20344u16, 31014u16, 64188u16, 52450u16, 38400u16, 41054u16, 28198u16, 22648u16, 666u16, 13508u16, 46942u16, 33024u16, 56290u16, 60860u16, 37295u16, 42993u16, 64787u16, 52045u16, 18647u16, 32393u16, 9323u16, 4661u16];


impl CRCu16 {
    pub fn crc10() -> CRCu16 {
        Self::create_crc(0x0233, 10, 0x0000, 0x0000, false)
    }

    pub fn crc10cdma2000() -> CRCu16 {
        Self::create_crc(0x03D9, 10, 0x03FF, 0x0000, false)
    }

    pub fn crc10gsm() -> CRCu16 {
        Self::create_crc(0x0175, 10, 0x0000, 0x03FF, false)
    }

    pub fn crc11() -> CRCu16 {
        Self::create_crc(0x0385, 11, 0x001a, 0x0000, false)
    }

    pub fn crc12() -> CRCu16 {
        Self::create_crc(0x080F, 12, 0x0000, 0x0000, false)
    }

    pub fn crc12cdma2000() -> CRCu16 {
        Self::create_crc(0x0F13, 12, 0x0FFF, 0x0000, false)
    }

    pub fn crc12gsm() -> CRCu16 {
        Self::create_crc(0x0D31, 12, 0x0000, 0x0FFF, false)
    }

    pub fn crc13bbc() -> CRCu16 {
        Self::create_crc(0x1CF5, 13, 0x0000, 0x0000, false)
    }

    pub fn crc14darc() -> CRCu16 {
        Self::create_crc(0x2804, 14, 0x0000, 0x0000, true)
    }

    pub fn crc14gsm() -> CRCu16 {
        Self::create_crc(0x202d, 14, 0x0000, 0x3FFF, false)
    }

    pub fn crc15can() -> CRCu16 {
        Self::create_crc(0x4599, 15, 0x0000, 0x0000, false)
    }

    pub fn crc15mpt1327() -> CRCu16 {
        Self::create_crc(0x6815, 15, 0x0000, 0x0001, false)
    }

    pub fn crc16() -> CRCu16 {
//         Self::create_crc(0xA001, 16, 0x0000, 0x0000, true)

        let lookup_table = REF_16_A001;
        Self::create_crc_with_exists_lookup_table(lookup_table, 16, 0x0000, 0x0000, true)
    }

    pub fn crc16ccitt_false() -> CRCu16 {
//         Self::create_crc(0x1021, 16, 0xFFFF, 0x0000, false)

        let lookup_table = NO_REF_16_1021;
        Self::create_crc_with_exists_lookup_table(lookup_table, 16, 0xFFFF, 0x0000, false)
    }

    pub fn crc16aug_ccitt() -> CRCu16 {
//         Self::create_crc(0x1021, 16, 0x1D0F, 0x0000, false)

        let lookup_table = NO_REF_16_1021;
        Self::create_crc_with_exists_lookup_table(lookup_table, 16, 0x1D0F, 0x0000, false)
    }

    pub fn crc16buypass() -> CRCu16 {
//         Self::create_crc(0x8005, 16, 0x0000, 0x0000, false)

        let lookup_table = NO_REF_16_8005;
        Self::create_crc_with_exists_lookup_table(lookup_table, 16, 0x0000, 0x0000, false)
    }

    pub fn crc16cdma2000() -> CRCu16 {
//         Self::create_crc(0xC867, 16, 0xFFFF, 0x0000, false)

        let lookup_table = NO_REF_16_C867;
        Self::create_crc_with_exists_lookup_table(lookup_table, 16, 0xFFFF, 0x0000, false)
    }

    pub fn crc16dds_110() -> CRCu16 {
//         Self::create_crc(0x8005, 16, 0x800D, 0x0000, false)

        let lookup_table = NO_REF_16_8005;
        Self::create_crc_with_exists_lookup_table(lookup_table, 16, 0x800D, 0x0000, false)
    }

    pub fn crc16dect_r() -> CRCu16 {
//         Self::create_crc(0x0589, 16, 0x0000, 0x0001, false)

        let lookup_table = NO_REF_16_0589;
        Self::create_crc_with_exists_lookup_table(lookup_table, 16, 0x0000, 0x0001, false)
    }

    pub fn crc16dect_x() -> CRCu16 {
//         Self::create_crc(0x0589, 16, 0x0000, 0x0000, false)

        let lookup_table = NO_REF_16_0589;
        Self::create_crc_with_exists_lookup_table(lookup_table, 16, 0x0000, 0x0000, false)
    }

    pub fn crc16dnp() -> CRCu16 {
//         Self::create_crc(0xA6BC, 16, 0x0000, 0xFFFF, true)

        let lookup_table = REF_16_A6BC;
        Self::create_crc_with_exists_lookup_table(lookup_table, 16, 0x0000, 0xFFFF, true)
    }

    pub fn crc16en_13757() -> CRCu16 {
//         Self::create_crc(0x3D65, 16, 0x0000, 0xFFFF, false)

        let lookup_table = NO_REF_16_3D65;
        Self::create_crc_with_exists_lookup_table(lookup_table, 16, 0x0000, 0xFFFF, false)
    }

    pub fn crc16genibus() -> CRCu16 {
//         Self::create_crc(0x1021, 16, 0xFFFF, 0xFFFF, false)

        let lookup_table = NO_REF_16_1021;
        Self::create_crc_with_exists_lookup_table(lookup_table, 16, 0xFFFF, 0xFFFF, false)
    }

    pub fn crc16maxim() -> CRCu16 {
//         Self::create_crc(0xA001, 16, 0x0000, 0xFFFF, true)

        let lookup_table = REF_16_A001;
        Self::create_crc_with_exists_lookup_table(lookup_table, 16, 0x0000, 0xFFFF, true)
    }

    pub fn crc16mcrf4cc() -> CRCu16 {
//         Self::create_crc(0x8408, 16, 0xFFFF, 0x0000, true)

        let lookup_table = REF_16_8408;
        Self::create_crc_with_exists_lookup_table(lookup_table, 16, 0xFFFF, 0x0000, true)
    }

    pub fn crc16riello() -> CRCu16 {
//        Self::create_crc(0x8408, 16, 0xB2AA, 0x0000, true)

        let lookup_table = REF_16_8408;
        Self::create_crc_with_exists_lookup_table(lookup_table, 16, 0xB2AA, 0x0000, true)
    }

    pub fn crc16t10_dif() -> CRCu16 {
//         Self::create_crc(0x8BB7, 16, 0x0000, 0x0000, false)

        let lookup_table = NO_REF_16_8BB7;
        Self::create_crc_with_exists_lookup_table(lookup_table, 16, 0x0000, 0x0000, false)
    }

    pub fn crc16teledisk() -> CRCu16 {
//         Self::create_crc(0xA097, 16, 0x0000, 0x0000, false)

        let lookup_table = REF_16_A097;
        Self::create_crc_with_exists_lookup_table(lookup_table, 16, 0x0000, 0x0000, false)
    }

    pub fn crc16tms13157() -> CRCu16 {
//         Self::create_crc(0x8408, 16, 0x89EC, 0x0000, true)

        let lookup_table = REF_16_8408;
        Self::create_crc_with_exists_lookup_table(lookup_table, 16, 0x89EC, 0x0000, true)
    }

    pub fn crc16usb() -> CRCu16 {
//         Self::create_crc(0xA001, 16, 0xFFFF, 0xFFFF, true)

        let lookup_table = REF_16_A001;
        Self::create_crc_with_exists_lookup_table(lookup_table, 16, 0xFFFF, 0xFFFF, true)
    }

    pub fn crc_a() -> CRCu16 {
//         Self::create_crc(0x8408, 16, 0xC6C6, 0x0000, true)

        let lookup_table = REF_16_8408;
        Self::create_crc_with_exists_lookup_table(lookup_table, 16, 0xC6C6, 0x0000, true)
    }

    pub fn crc16kermit() -> CRCu16 {
//         Self::create_crc(0x8408, 16, 0x0000, 0x0000, true)

        let lookup_table = REF_16_8408;
        Self::create_crc_with_exists_lookup_table(lookup_table, 16, 0x0000, 0x0000, true)
    }

    pub fn crc16modbus() -> CRCu16 {
//         Self::create_crc(0xA001, 16, 0xFFFF, 0x0000, true)

        let lookup_table = REF_16_A001;
        Self::create_crc_with_exists_lookup_table(lookup_table, 16, 0xFFFF, 0x0000, true)
    }

    pub fn crc16_x25() -> CRCu16 {
//         Self::create_crc(0x8408, 16, 0xFFFF, 0xFFFF, true)

        let lookup_table = REF_16_8408;
        Self::create_crc_with_exists_lookup_table(lookup_table, 16, 0xFFFF, 0xFFFF, true)
    }

    pub fn crc16xmodem() -> CRCu16 {
//         Self::create_crc(0x1021, 16, 0x0000, 0x0000, false)

        let lookup_table = NO_REF_16_1021;
        Self::create_crc_with_exists_lookup_table(lookup_table, 16, 0x0000, 0x0000, false)
    }
}

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

    use std::fmt::Write;

    #[test]
    fn print_lookup_table() {
        let crc = CRCu16::crc16kermit();

        let mut s = String::new();

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

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

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