crc/
lib.rs

1//! # crc
2//! Rust implementation of CRC.
3//!
4//! ### Examples
5//! Using a well-known algorithm:
6//! ```rust
7//! const X25: crc::Crc<u16> = crc::Crc::<u16>::new(&crc::CRC_16_IBM_SDLC);
8//! assert_eq!(X25.checksum(b"123456789"), 0x906e);
9//! ```
10//!
11//! Using a custom algorithm:
12//! ```rust
13//! const CUSTOM_ALG: crc::Algorithm<u16> = crc::Algorithm {
14//!     width: 16,
15//!     poly: 0x8005,
16//!     init: 0xffff,
17//!     refin: false,
18//!     refout: false,
19//!     xorout: 0x0000,
20//!     check: 0xaee7,
21//!     residue: 0x0000
22//! };
23//! let crc = crc::Crc::<u16>::new(&CUSTOM_ALG);
24//! let mut digest = crc.digest();
25//! digest.update(b"123456789");
26//! assert_eq!(digest.finalize(), 0xaee7);
27//! ```
28#![no_std]
29#![forbid(unsafe_code)]
30
31pub use crc_catalog::algorithm::*;
32pub use crc_catalog::{Algorithm, Width};
33
34mod crc128;
35mod crc16;
36mod crc32;
37mod crc64;
38mod crc8;
39mod table;
40mod util;
41
42/// A trait for CRC implementations.
43pub trait Implementation: private::Sealed {
44    /// Associated data necessary for the implementation (e.g. lookup tables).
45    type Data<W>;
46}
47
48/// A table-based implementation of the CRC algorithm, with `L` lanes.
49/// The number of entries in the lookup table is `L * 256`.
50#[derive(Copy, Clone)]
51pub struct Table<const L: usize> {}
52
53/// An implementation of the CRC algorithm with no lookup table.
54pub type NoTable = Table<0>;
55
56type DefaultImpl = Table<1>;
57
58impl<const L: usize> Implementation for Table<L> {
59    type Data<W> = [[W; 256]; L];
60}
61
62mod private {
63    pub trait Sealed {}
64    impl<const L: usize> Sealed for super::Table<L> {}
65}
66
67/// Crc instance with a specific width, algorithm, and implementation.
68#[derive(Clone)]
69pub struct Crc<W: Width, I: Implementation = DefaultImpl> {
70    pub algorithm: &'static Algorithm<W>,
71    data: I::Data<W>,
72}
73
74#[derive(Clone)]
75pub struct Digest<'a, W: Width, I: Implementation = DefaultImpl> {
76    crc: &'a Crc<W, I>,
77    value: W,
78}
79
80#[cfg(test)]
81mod test {
82    use super::{Crc, CRC_32_ISCSI};
83
84    #[test]
85    fn test_clone() {
86        const CRC: Crc<u32> = Crc::<u32>::new(&CRC_32_ISCSI);
87        let _crc = CRC.clone();
88    }
89}