crc_any/
crc_u32.rs

1#[cfg(feature = "alloc")]
2use alloc::fmt::{self, Debug, Display, Formatter};
3#[cfg(feature = "alloc")]
4use alloc::vec::Vec;
5
6#[cfg(feature = "heapless")]
7use heapless::Vec as HeaplessVec;
8
9use crate::{constants::crc_u32::*, lookup_table::LookUpTable};
10
11#[allow(clippy::upper_case_acronyms)]
12/// This struct can help you compute a CRC-32 (or CRC-x where **x** is equal or less than `32`) value.
13pub struct CRCu32 {
14    by_table:        bool,
15    poly:            u32,
16    lookup_table:    LookUpTable<u32>,
17    sum:             u32,
18    pub(crate) bits: u8,
19    high_bit:        u32,
20    mask:            u32,
21    initial:         u32,
22    final_xor:       u32,
23    reflect:         bool,
24    reorder:         bool,
25}
26
27#[cfg(feature = "alloc")]
28impl Debug for CRCu32 {
29    #[inline]
30    fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
31        if self.by_table {
32            debug_helper::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);
33        } else {
34            debug_helper::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);
35        }
36    }
37}
38
39#[cfg(feature = "alloc")]
40impl Display for CRCu32 {
41    #[inline]
42    fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
43        f.write_fmt(format_args!("0x{:01$X}", self.get_crc(), (self.bits as usize + 3) >> 2))
44    }
45}
46
47impl CRCu32 {
48    /// Create a `CRCu32` instance by providing the length of bits, expression, reflection, an initial value and a final xor value.
49    pub fn create_crc(poly: u32, bits: u8, initial: u32, final_xor: u32, reflect: bool) -> CRCu32 {
50        debug_assert!(bits <= 32 && bits > 0);
51
52        if bits % 8 == 0 {
53            let lookup_table = if reflect {
54                LookUpTable::Dynamic(Self::crc_reflect_table(poly))
55            } else {
56                LookUpTable::Dynamic(Self::crc_table(poly, bits))
57            };
58
59            Self::create_crc_with_exists_lookup_table(
60                lookup_table,
61                bits,
62                initial,
63                final_xor,
64                reflect,
65            )
66        } else {
67            Self::create(
68                false,
69                LookUpTable::Static(&[0u32; 256]),
70                poly,
71                bits,
72                initial,
73                final_xor,
74                reflect,
75            )
76        }
77    }
78
79    #[inline]
80    pub(crate) fn create_crc_with_exists_lookup_table(
81        lookup_table: LookUpTable<u32>,
82        bits: u8,
83        initial: u32,
84        final_xor: u32,
85        reflect: bool,
86    ) -> CRCu32 {
87        debug_assert!(bits % 8 == 0);
88
89        Self::create(true, lookup_table, 0, bits, initial, final_xor, reflect)
90    }
91
92    #[inline]
93    fn create(
94        by_table: bool,
95        lookup_table: LookUpTable<u32>,
96        mut poly: u32,
97        bits: u8,
98        initial: u32,
99        final_xor: u32,
100        reflect: bool,
101    ) -> CRCu32 {
102        let high_bit = 1 << u32::from(bits - 1);
103        let mask = ((high_bit - 1) << 1) | 1;
104
105        let sum = if reflect { Self::reflect_function(high_bit, initial) } else { initial };
106
107        if !by_table && reflect {
108            poly = Self::reflect_function(high_bit, poly);
109        }
110
111        CRCu32 {
112            by_table,
113            poly,
114            lookup_table,
115            sum,
116            bits,
117            high_bit,
118            mask,
119            initial,
120            final_xor,
121            reflect,
122            reorder: false,
123        }
124    }
125
126    #[inline]
127    fn reflect_function(high_bit: u32, n: u32) -> u32 {
128        let mut i = high_bit;
129        let mut j = 1;
130        let mut out = 0;
131
132        while i != 0 {
133            if n & i != 0 {
134                out |= j;
135            }
136
137            j <<= 1;
138            i >>= 1;
139        }
140
141        out
142    }
143
144    #[inline]
145    fn reflect_method(&self, n: u32) -> u32 {
146        Self::reflect_function(self.high_bit, n)
147    }
148
149    /// Digest some data.
150    pub fn digest<T: ?Sized + AsRef<[u8]>>(&mut self, data: &T) {
151        if self.by_table {
152            if self.bits == 8 {
153                for n in data.as_ref().iter().copied() {
154                    let index = (self.sum as u8 ^ n) as usize;
155                    self.sum = self.lookup_table[index];
156                }
157            } else if self.reflect {
158                for n in data.as_ref().iter().copied() {
159                    let index = ((self.sum as u8) ^ n) as usize;
160                    self.sum = (self.sum >> 8) ^ self.lookup_table[index];
161                }
162            } else {
163                for n in data.as_ref().iter().copied() {
164                    let index = ((self.sum >> u32::from(self.bits - 8)) as u8 ^ n) as usize;
165                    self.sum = (self.sum << 8) ^ self.lookup_table[index];
166                }
167            }
168        } else if self.reflect {
169            for n in data.as_ref().iter().copied() {
170                let n = super::crc_u8::CRCu8::reflect_function(0x80, n);
171
172                let mut i = 0x80;
173
174                while i != 0 {
175                    let mut bit = self.sum & self.high_bit;
176
177                    self.sum <<= 1;
178
179                    if n & i != 0 {
180                        bit ^= self.high_bit;
181                    }
182
183                    if bit != 0 {
184                        self.sum ^= self.poly;
185                    }
186
187                    i >>= 1;
188                }
189            }
190        } else {
191            for n in data.as_ref().iter().copied() {
192                let mut i = 0x80;
193
194                while i != 0 {
195                    let mut bit = self.sum & self.high_bit;
196
197                    self.sum <<= 1;
198
199                    if n & i != 0 {
200                        bit ^= self.high_bit;
201                    }
202
203                    if bit != 0 {
204                        self.sum ^= self.poly;
205                    }
206
207                    i >>= 1;
208                }
209            }
210        }
211    }
212
213    /// Reset the sum.
214    pub fn reset(&mut self) {
215        self.sum = self.initial;
216    }
217
218    /// Get the current CRC value (it always returns a `u32` value). You can continue calling `digest` method even after getting a CRC value.
219    pub fn get_crc(&self) -> u32 {
220        let sum = if self.by_table || !self.reflect {
221            (self.sum ^ self.final_xor) & self.mask
222        } else {
223            (self.reflect_method(self.sum) ^ self.final_xor) & self.mask
224        };
225
226        if self.reorder {
227            let mut new_sum = 0;
228
229            let e = (self.bits as u32 + 7) >> 3;
230
231            let e_dec = e - 1;
232
233            for i in 0..e {
234                new_sum |= ((sum >> ((e_dec - i) * 8)) & 0xFF) << (i * 8);
235            }
236
237            new_sum
238        } else {
239            sum
240        }
241    }
242
243    fn crc_reflect_table(poly_rev: u32) -> [u32; 256] {
244        let mut lookup_table = [0u32; 256];
245
246        for (i, e) in lookup_table.iter_mut().enumerate() {
247            let mut v = i as u32;
248
249            #[allow(clippy::branches_sharing_code)]
250            for _ in 0..8u8 {
251                if v & 1 != 0 {
252                    v >>= 1;
253                    v ^= poly_rev;
254                } else {
255                    v >>= 1;
256                }
257            }
258
259            *e = v;
260        }
261
262        lookup_table
263    }
264
265    fn crc_table(poly: u32, bits: u8) -> [u32; 256] {
266        let mut lookup_table = [0u32; 256];
267
268        let mask1 = 1u32 << u32::from(bits - 1);
269
270        let mask2 = ((mask1 - 1) << 1) | 1;
271
272        for (i, e) in lookup_table.iter_mut().enumerate() {
273            let mut v = i as u32;
274
275            #[allow(clippy::branches_sharing_code)]
276            for _ in 0..bits {
277                if v & mask1 == 0 {
278                    v <<= 1;
279                } else {
280                    v <<= 1;
281                    v ^= poly;
282                }
283            }
284
285            *e = v & mask2;
286        }
287
288        lookup_table
289    }
290}
291
292#[cfg(feature = "alloc")]
293impl CRCu32 {
294    /// 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.
295    #[inline]
296    pub fn get_crc_vec_le(&mut self) -> Vec<u8> {
297        let crc = self.get_crc();
298
299        let e = (self.bits as usize + 7) >> 3;
300
301        crc.to_le_bytes()[..e].to_vec()
302    }
303
304    /// 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.
305    #[inline]
306    pub fn get_crc_vec_be(&mut self) -> Vec<u8> {
307        let crc = self.get_crc();
308
309        let e = (self.bits as usize + 7) >> 3;
310
311        crc.to_be_bytes()[(4 - e)..].to_vec()
312    }
313}
314
315#[cfg(feature = "heapless")]
316impl CRCu32 {
317    /// Get the current CRC value (it always returns a heapless vec instance with a length corresponding to the CRC bits). You can continue calling `digest` method even after getting a CRC value.
318    #[inline]
319    pub fn get_crc_heapless_vec_le(&mut self) -> HeaplessVec<u8, 4> {
320        let crc = self.get_crc();
321
322        let e = (self.bits as usize + 7) >> 3;
323
324        let mut vec = HeaplessVec::new();
325
326        vec.extend_from_slice(&crc.to_le_bytes()[..e]).unwrap();
327
328        vec
329    }
330
331    /// Get the current CRC value (it always returns a heapless vec instance with a length corresponding to the CRC bits). You can continue calling `digest` method even after getting a CRC value.
332    #[inline]
333    pub fn get_crc_heapless_vec_be(&mut self) -> HeaplessVec<u8, 4> {
334        let crc = self.get_crc();
335
336        let e = (self.bits as usize + 7) >> 3;
337
338        let mut vec = HeaplessVec::new();
339
340        vec.extend_from_slice(&crc.to_be_bytes()[(4 - e)..]).unwrap();
341
342        vec
343    }
344}
345
346impl CRCu32 {
347    /// |Check|Poly|Init|Ref|XorOut|
348    /// |---|---|---|---|---|
349    /// |0x04F03|0x1685B|0x00000|false|0x00000|
350    ///
351    /// ```
352    /// # use crc_any::CRCu32;
353    /// let mut crc = CRCu32::crc17can();
354    /// crc.digest(b"123456789");
355    #[cfg_attr(feature = "alloc", doc = "assert_eq!(\"0x04F03\", &crc.to_string());")]
356    /// ```
357    pub fn crc17can() -> CRCu32 {
358        Self::create_crc(0x0001685B, 17, 0x00000000, 0x00000000, false)
359    }
360
361    /// |Check|Poly|Init|Ref|XorOut|
362    /// |---|---|---|---|---|
363    /// |0x0ED841|0x102899|0x000000|false|0x000000|
364    ///
365    /// ```
366    /// # use crc_any::CRCu32;
367    /// let mut crc = CRCu32::crc21can();
368    /// crc.digest(b"123456789");
369    #[cfg_attr(feature = "alloc", doc = "assert_eq!(\"0x0ED841\", &crc.to_string());")]
370    /// ```
371    pub fn crc21can() -> CRCu32 {
372        Self::create_crc(0x00102899, 21, 0x00000000, 0x00000000, false)
373    }
374
375    /// |Check|Poly|Init|Ref|XorOut|
376    /// |---|---|---|---|---|
377    /// |0x21CF02|0x864CFB|0xB704CE|false|0x000000|
378    ///
379    /// ```
380    /// # use crc_any::CRCu32;
381    /// let mut crc = CRCu32::crc24();
382    /// crc.digest(b"123456789");
383    #[cfg_attr(feature = "alloc", doc = "assert_eq!(\"0x21CF02\", &crc.to_string());")]
384    /// ```
385    pub fn crc24() -> CRCu32 {
386        // Self::create_crc(0x00864CFB, 24, 0x00B704CE, 0x00000000, false)
387
388        let lookup_table = LookUpTable::Static(&NO_REF_24_00864CFB);
389        Self::create_crc_with_exists_lookup_table(lookup_table, 24, 0x00B704CE, 0x00000000, false)
390    }
391
392    /// |Check|Poly|Init|Ref|XorOut|
393    /// |---|---|---|---|---|
394    /// |0xC25A56|0x00065B (rev: 0xDA6000)|0x555555|true|0x000000|
395    ///
396    /// ```
397    /// # use crc_any::CRCu32;
398    /// let mut crc = CRCu32::crc24ble();
399    /// crc.digest(b"123456789");
400    #[cfg_attr(feature = "alloc", doc = "assert_eq!(\"0xC25A56\", &crc.to_string());")]
401    /// ```
402    pub fn crc24ble() -> CRCu32 {
403        // Self::create_crc(0x00DA6000, 24, 0x00555555, 0x00000000, true)
404
405        let lookup_table = LookUpTable::Static(&REF_24_00DA6000);
406        Self::create_crc_with_exists_lookup_table(lookup_table, 24, 0x00555555, 0x00000000, true)
407    }
408
409    /// |Check|Poly|Init|Ref|XorOut|
410    /// |---|---|---|---|---|
411    /// |0x7979BD|0x5D6DCB|0xFEDCBA|false|0x000000|
412    ///
413    /// ```
414    /// # use crc_any::CRCu32;
415    /// let mut crc = CRCu32::crc24flexray_a();
416    /// crc.digest(b"123456789");
417    #[cfg_attr(feature = "alloc", doc = "assert_eq!(\"0x7979BD\", &crc.to_string());")]
418    /// ```
419    pub fn crc24flexray_a() -> CRCu32 {
420        // Self::create_crc(0x005D6DCB, 24, 0x00FEDCBA, 0x00000000, false)
421
422        let lookup_table = LookUpTable::Static(&NO_REF_24_005D6DCB);
423        Self::create_crc_with_exists_lookup_table(lookup_table, 24, 0x00FEDCBA, 0x00000000, false)
424    }
425
426    /// |Check|Poly|Init|Ref|XorOut|
427    /// |---|---|---|---|---|
428    /// |0x1F23B8|0x5D6DCB|0xABCDEF|false|0x000000|
429    ///
430    /// ```
431    /// # use crc_any::CRCu32;
432    /// let mut crc = CRCu32::crc24flexray_b();
433    /// crc.digest(b"123456789");
434    #[cfg_attr(feature = "alloc", doc = "assert_eq!(\"0x1F23B8\", &crc.to_string());")]
435    /// ```
436    pub fn crc24flexray_b() -> CRCu32 {
437        // Self::create_crc(0x005D6DCB, 24, 0x00ABCDEF, 0x00000000, false)
438
439        let lookup_table = LookUpTable::Static(&NO_REF_24_005D6DCB);
440        Self::create_crc_with_exists_lookup_table(lookup_table, 24, 0x00ABCDEF, 0x00000000, false)
441    }
442
443    /// |Check|Poly|Init|Ref|XorOut|
444    /// |---|---|---|---|---|
445    /// |0xCDE703|0x864CFB|0x000000|false|0x000000|
446    ///
447    /// ```
448    /// # use crc_any::CRCu32;
449    /// let mut crc = CRCu32::crc24lte_a();
450    /// crc.digest(b"123456789");
451    #[cfg_attr(feature = "alloc", doc = "assert_eq!(\"0xCDE703\", &crc.to_string());")]
452    /// ```
453    pub fn crc24lte_a() -> CRCu32 {
454        // Self::create_crc(0x00864CFB, 24, 0x00000000, 0x00000000, false)
455
456        let lookup_table = LookUpTable::Static(&NO_REF_24_00864CFB);
457        Self::create_crc_with_exists_lookup_table(lookup_table, 24, 0x00000000, 0x00000000, false)
458    }
459
460    /// |Check|Poly|Init|Ref|XorOut|
461    /// |---|---|---|---|---|
462    /// |0x23EF52|0x800063|0x000000|false|0x000000|
463    ///
464    /// ```
465    /// # use crc_any::CRCu32;
466    /// let mut crc = CRCu32::crc24lte_b();
467    /// crc.digest(b"123456789");
468    #[cfg_attr(feature = "alloc", doc = "assert_eq!(\"0x23EF52\", &crc.to_string());")]
469    /// ```
470    pub fn crc24lte_b() -> CRCu32 {
471        // Self::create_crc(0x00800063, 24, 0x00000000, 0x00000000, false)
472
473        let lookup_table = LookUpTable::Static(&NO_REF_24_00800063);
474        Self::create_crc_with_exists_lookup_table(lookup_table, 24, 0x00000000, 0x00000000, false)
475    }
476
477    /// |Check|Poly|Init|Ref|XorOut|
478    /// |---|---|---|---|---|
479    /// |0x200FA5|0x800063|0xFFFFFF|false|0xFFFFFF|
480    ///
481    /// ```
482    /// # use crc_any::CRCu32;
483    /// let mut crc = CRCu32::crc24os9();
484    /// crc.digest(b"123456789");
485    #[cfg_attr(feature = "alloc", doc = "assert_eq!(\"0x200FA5\", &crc.to_string());")]
486    /// ```
487    pub fn crc24os9() -> CRCu32 {
488        // Self::create_crc(0x00800063, 24, 0x00FFFFFF, 0x00FFFFFF, false)
489
490        let lookup_table = LookUpTable::Static(&NO_REF_24_00800063);
491        Self::create_crc_with_exists_lookup_table(lookup_table, 24, 0x00FFFFFF, 0x00FFFFFF, false)
492    }
493
494    /// |Check|Poly|Init|Ref|XorOut|
495    /// |---|---|---|---|---|
496    /// |0x04C34ABF|0x2030B9C7|0x3FFFFFFF|false|0x3FFFFFFF|
497    ///
498    /// ```
499    /// # use crc_any::CRCu32;
500    /// let mut crc = CRCu32::crc30cdma();
501    /// crc.digest(b"123456789");
502    #[cfg_attr(feature = "alloc", doc = "assert_eq!(\"0x04C34ABF\", &crc.to_string());")]
503    /// ```
504    pub fn crc30cdma() -> CRCu32 {
505        Self::create_crc(0x2030B9C7, 30, 0x3FFFFFFF, 0x3FFFFFFF, false)
506    }
507
508    /// |Check|Poly|Init|Ref|XorOut|
509    /// |---|---|---|---|---|
510    /// |0xCBF43926|0x04C11DB7 (rev: 0xEDB88320)|0xFFFFFFFF|true|0xFFFFFFFF|
511    ///
512    /// ```
513    /// # use crc_any::CRCu32;
514    /// let mut crc = CRCu32::crc32();
515    /// crc.digest(b"123456789");
516    #[cfg_attr(feature = "alloc", doc = "assert_eq!(\"0xCBF43926\", &crc.to_string());")]
517    /// ```
518    pub fn crc32() -> CRCu32 {
519        // Self::create_crc(0xEDB88320, 32, 0xFFFFFFFF, 0xFFFFFFFF, true)
520
521        let lookup_table = LookUpTable::Static(&REF_32_EDB88320);
522        Self::create_crc_with_exists_lookup_table(lookup_table, 32, 0xFFFFFFFF, 0xFFFFFFFF, true)
523    }
524
525    /// |Check|Poly|Init|Ref|XorOut|
526    /// |---|---|---|---|---|
527    /// |0x181989FC|0x04C11DB7|0xFFFFFFFF|false|0xFFFFFFFF|
528    ///
529    /// **Output will be reversed by bytes.**
530    ///
531    /// ```
532    /// # use crc_any::CRCu32;
533    /// let mut crc = CRCu32::crc32mhash();
534    /// crc.digest(b"123456789");
535    #[cfg_attr(feature = "alloc", doc = "assert_eq!(\"0x181989FC\", &crc.to_string());")]
536    /// ```
537    pub fn crc32mhash() -> CRCu32 {
538        // let mut crc = Self::create_crc(0x04C11DB7, 32, 0xFFFFFFFF, 0xFFFFFFFF, false);
539
540        let lookup_table = LookUpTable::Static(&NO_REF_32_04C11DB7);
541
542        let mut crc = Self::create_crc_with_exists_lookup_table(
543            lookup_table,
544            32,
545            0xFFFFFFFF,
546            0xFFFFFFFF,
547            false,
548        );
549
550        crc.reorder = true;
551
552        crc
553    }
554
555    /// |Check|Poly|Init|Ref|XorOut|
556    /// |---|---|---|---|---|
557    /// |0xFC891918|0x04C11DB7|0xFFFFFFFF|false|0xFFFFFFFF|
558    ///
559    /// ```
560    /// # use crc_any::CRCu32;
561    /// let mut crc = CRCu32::crc32bzip2();
562    /// crc.digest(b"123456789");
563    #[cfg_attr(feature = "alloc", doc = "assert_eq!(\"0xFC891918\", &crc.to_string());")]
564    /// ```
565    pub fn crc32bzip2() -> CRCu32 {
566        // Self::create_crc(0x04C11DB7, 32, 0xFFFFFFFF, 0xFFFFFFFF, false)
567
568        let lookup_table = LookUpTable::Static(&NO_REF_32_04C11DB7);
569        Self::create_crc_with_exists_lookup_table(lookup_table, 32, 0xFFFFFFFF, 0xFFFFFFFF, false)
570    }
571
572    /// |Check|Poly|Init|Ref|XorOut|
573    /// |---|---|---|---|---|
574    /// |0xE3069283|0x1EDC6F41 (rev: 0x82F63B78)|0xFFFFFFFF|true|0xFFFFFFFF|
575    ///
576    /// ```
577    /// # use crc_any::CRCu32;
578    /// let mut crc = CRCu32::crc32c();
579    /// crc.digest(b"123456789");
580    #[cfg_attr(feature = "alloc", doc = "assert_eq!(\"0xE3069283\", &crc.to_string());")]
581    /// ```
582    pub fn crc32c() -> CRCu32 {
583        // Self::create_crc(0x82F63B78, 32, 0xFFFFFFFF, 0xFFFFFFFF, true)
584
585        let lookup_table = LookUpTable::Static(&REF_32_82F63B78);
586        Self::create_crc_with_exists_lookup_table(lookup_table, 32, 0xFFFFFFFF, 0xFFFFFFFF, true)
587    }
588
589    /// |Check|Poly|Init|Ref|XorOut|
590    /// |---|---|---|---|---|
591    /// |0x87315576|0xA833982B (rev: 0xD419CC15)|0xFFFFFFFF|true|0xFFFFFFFF|
592    ///
593    /// ```
594    /// # use crc_any::CRCu32;
595    /// let mut crc = CRCu32::crc32d();
596    /// crc.digest(b"123456789");
597    #[cfg_attr(feature = "alloc", doc = "assert_eq!(\"0x87315576\", &crc.to_string());")]
598    /// ```
599    pub fn crc32d() -> CRCu32 {
600        // Self::create_crc(0xD419CC15, 32, 0xFFFFFFFF, 0xFFFFFFFF, true)
601
602        let lookup_table = LookUpTable::Static(&REF_32_D419CC15);
603        Self::create_crc_with_exists_lookup_table(lookup_table, 32, 0xFFFFFFFF, 0xFFFFFFFF, true)
604    }
605
606    /// |Check|Poly|Init|Ref|XorOut|
607    /// |---|---|---|---|---|
608    /// |0x0376E6E7|0x04C11DB7|0xFFFFFFFF|false|0x00000000|
609    ///
610    /// ```
611    /// # use crc_any::CRCu32;
612    /// let mut crc = CRCu32::crc32mpeg2();
613    /// crc.digest(b"123456789");
614    #[cfg_attr(feature = "alloc", doc = "assert_eq!(\"0x0376E6E7\", &crc.to_string());")]
615    /// ```
616    pub fn crc32mpeg2() -> CRCu32 {
617        // Self::create_crc(0x04C11DB7, 32, 0xFFFFFFFF, 0x00000000, false)
618
619        let lookup_table = LookUpTable::Static(&NO_REF_32_04C11DB7);
620        Self::create_crc_with_exists_lookup_table(lookup_table, 32, 0xFFFFFFFF, 0x00000000, false)
621    }
622
623    /// |Check|Poly|Init|Ref|XorOut|
624    /// |---|---|---|---|---|
625    /// |0x765E7680|0x04C11DB7|0x00000000|false|0xFFFFFFFF|
626    ///
627    /// ```
628    /// # use crc_any::CRCu32;
629    /// let mut crc = CRCu32::crc32posix();
630    /// crc.digest(b"123456789");
631    #[cfg_attr(feature = "alloc", doc = "assert_eq!(\"0x765E7680\", &crc.to_string());")]
632    /// ```
633    pub fn crc32posix() -> CRCu32 {
634        // Self::create_crc(0x04C11DB7, 32, 0x00000000, 0xFFFFFFFF, false)
635
636        let lookup_table = LookUpTable::Static(&NO_REF_32_04C11DB7);
637        Self::create_crc_with_exists_lookup_table(lookup_table, 32, 0x00000000, 0xFFFFFFFF, false)
638    }
639
640    /// |Check|Poly|Init|Ref|XorOut|
641    /// |---|---|---|---|---|
642    /// |0x3010BF7F|0x814141AB|0x00000000|false|0x00000000|
643    ///
644    /// ```
645    /// # use crc_any::CRCu32;
646    /// let mut crc = CRCu32::crc32q();
647    /// crc.digest(b"123456789");
648    #[cfg_attr(feature = "alloc", doc = "assert_eq!(\"0x3010BF7F\", &crc.to_string());")]
649    /// ```
650    pub fn crc32q() -> CRCu32 {
651        // Self::create_crc(0x814141AB, 32, 0x00000000, 0x00000000, false)
652
653        let lookup_table = LookUpTable::Static(&NO_REF_32_814141AB);
654        Self::create_crc_with_exists_lookup_table(lookup_table, 32, 0x00000000, 0x00000000, false)
655    }
656
657    /// |Check|Poly|Init|Ref|XorOut|
658    /// |---|---|---|---|---|
659    /// |0x340BC6D9|0x04C11DB7 (rev: 0xEDB88320)|0xFFFFFFFF|true|0x00000000|
660    ///
661    /// ```
662    /// # use crc_any::CRCu32;
663    /// let mut crc = CRCu32::crc32jamcrc();
664    /// crc.digest(b"123456789");
665    #[cfg_attr(feature = "alloc", doc = "assert_eq!(\"0x340BC6D9\", &crc.to_string());")]
666    /// ```
667    pub fn crc32jamcrc() -> CRCu32 {
668        // Self::create_crc(0xEDB88320, 32, 0xFFFFFFFF, 0x00000000, true)
669
670        let lookup_table = LookUpTable::Static(&REF_32_EDB88320);
671        Self::create_crc_with_exists_lookup_table(lookup_table, 32, 0xFFFFFFFF, 0x00000000, true)
672    }
673
674    /// |Check|Poly|Init|Ref|XorOut|
675    /// |---|---|---|---|---|
676    /// |0xBD0BE338|0x000000AF|0x00000000|false|0x00000000|
677    ///
678    /// ```
679    /// # use crc_any::CRCu32;
680    /// let mut crc = CRCu32::crc32xfer();
681    /// crc.digest(b"123456789");
682    #[cfg_attr(feature = "alloc", doc = "assert_eq!(\"0xBD0BE338\", &crc.to_string());")]
683    /// ```
684    pub fn crc32xfer() -> CRCu32 {
685        // Self::create_crc(0x000000AF, 32, 0x00000000, 0x00000000, false)
686
687        let lookup_table = LookUpTable::Static(&NO_REF_32_000000AF);
688        Self::create_crc_with_exists_lookup_table(lookup_table, 32, 0x00000000, 0x00000000, false)
689    }
690}
691
692#[cfg(all(feature = "development", test))]
693mod tests {
694    use alloc::{fmt::Write, string::String};
695
696    use super::CRCu32;
697
698    #[test]
699    fn print_lookup_table() {
700        let crc = CRCu32::crc24ble();
701
702        let mut s = String::new();
703
704        for n in crc.lookup_table.iter().take(255) {
705            s.write_fmt(format_args!("{}u32, ", n)).unwrap();
706        }
707
708        s.write_fmt(format_args!("{}u32", crc.lookup_table[255])).unwrap();
709
710        println!("let lookup_table = [{}];", s);
711    }
712}