#![cfg_attr(not(feature = "std"), no_std)]
#[cfg(feature = "alloc")]
#[macro_use]
extern crate alloc;
#[cfg(feature = "alloc")]
#[macro_use]
extern crate debug_helper;
#[cfg(feature = "alloc")]
use alloc::fmt::{self, Display, Formatter};
#[cfg(feature = "alloc")]
use alloc::vec::Vec;
#[cfg(feature = "heapless")]
use heapless::consts::U8;
#[cfg(feature = "heapless")]
use heapless::Vec as HeaplessVec;
mod constants;
mod crc_u16;
mod crc_u32;
mod crc_u64;
mod crc_u8;
pub use crc_u16::CRCu16;
pub use crc_u32::CRCu32;
pub use crc_u64::CRCu64;
pub use crc_u8::CRCu8;
#[allow(clippy::upper_case_acronyms, clippy::large_enum_variant)]
#[cfg_attr(feature = "alloc", derive(Debug))]
pub enum CRC {
CRCu8(CRCu8),
CRCu16(CRCu16),
CRCu32(CRCu32),
CRCu64(CRCu64),
}
#[cfg(feature = "alloc")]
impl Display for CRC {
#[inline]
fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
match self {
CRC::CRCu8(crc) => Display::fmt(crc, f),
CRC::CRCu16(crc) => Display::fmt(crc, f),
CRC::CRCu32(crc) => Display::fmt(crc, f),
CRC::CRCu64(crc) => Display::fmt(crc, f),
}
}
}
impl CRC {
#[inline]
pub fn create_crc(poly: u64, bits: u8, initial: u64, final_xor: u64, reflect: bool) -> CRC {
if bits <= 8 {
Self::create_crc_u8(poly as u8, bits, initial as u8, final_xor as u8, reflect)
} else if bits <= 16 {
Self::create_crc_u16(poly as u16, bits, initial as u16, final_xor as u16, reflect)
} else if bits <= 32 {
Self::create_crc_u32(poly as u32, bits, initial as u32, final_xor as u32, reflect)
} else if bits <= 64 {
Self::create_crc_u64(poly, bits, initial, final_xor, reflect)
} else {
unimplemented!()
}
}
#[inline]
pub fn create_crc_u8(poly: u8, bits: u8, initial: u8, final_xor: u8, reflect: bool) -> CRC {
let crc = CRCu8::create_crc(poly, bits, initial, final_xor, reflect);
CRC::CRCu8(crc)
}
#[inline]
pub fn create_crc_u16(poly: u16, bits: u8, initial: u16, final_xor: u16, reflect: bool) -> CRC {
let crc = CRCu16::create_crc(poly, bits, initial, final_xor, reflect);
CRC::CRCu16(crc)
}
#[inline]
pub fn create_crc_u32(poly: u32, bits: u8, initial: u32, final_xor: u32, reflect: bool) -> CRC {
let crc = CRCu32::create_crc(poly, bits, initial, final_xor, reflect);
CRC::CRCu32(crc)
}
#[inline]
pub fn create_crc_u64(poly: u64, bits: u8, initial: u64, final_xor: u64, reflect: bool) -> CRC {
let crc = CRCu64::create_crc(poly, bits, initial, final_xor, reflect);
CRC::CRCu64(crc)
}
#[inline]
pub fn digest<T: ?Sized + AsRef<[u8]>>(&mut self, data: &T) {
match self {
CRC::CRCu8(crc) => crc.digest(data),
CRC::CRCu16(crc) => crc.digest(data),
CRC::CRCu32(crc) => crc.digest(data),
CRC::CRCu64(crc) => crc.digest(data),
}
}
#[inline]
pub fn reset(&mut self) {
match self {
CRC::CRCu8(crc) => crc.reset(),
CRC::CRCu16(crc) => crc.reset(),
CRC::CRCu32(crc) => crc.reset(),
CRC::CRCu64(crc) => crc.reset(),
}
}
#[inline]
pub fn get_crc(&mut self) -> u64 {
match self {
CRC::CRCu8(crc) => u64::from(crc.get_crc()),
CRC::CRCu16(crc) => u64::from(crc.get_crc()),
CRC::CRCu32(crc) => u64::from(crc.get_crc()),
CRC::CRCu64(crc) => crc.get_crc(),
}
}
}
#[cfg(feature = "alloc")]
impl CRC {
#[inline]
pub fn get_crc_vec_le(&mut self) -> Vec<u8> {
match self {
CRC::CRCu8(crc) => vec![crc.get_crc()],
CRC::CRCu16(crc) => crc.get_crc_vec_le(),
CRC::CRCu32(crc) => crc.get_crc_vec_le(),
CRC::CRCu64(crc) => crc.get_crc_vec_le(),
}
}
#[inline]
pub fn get_crc_vec_be(&mut self) -> Vec<u8> {
match self {
CRC::CRCu8(crc) => vec![crc.get_crc()],
CRC::CRCu16(crc) => crc.get_crc_vec_be(),
CRC::CRCu32(crc) => crc.get_crc_vec_be(),
CRC::CRCu64(crc) => crc.get_crc_vec_be(),
}
}
}
#[cfg(feature = "heapless")]
impl CRC {
pub fn get_crc_heapless_vec_le(&mut self) -> HeaplessVec<u8, U8> {
let mut vec = HeaplessVec::new();
let bits = match self {
CRC::CRCu8(crc) => f64::from(crc.bits),
CRC::CRCu16(crc) => f64::from(crc.bits),
CRC::CRCu32(crc) => f64::from(crc.bits),
CRC::CRCu64(crc) => f64::from(crc.bits),
};
let e = ((bits + 7f64) / 8f64) as u64;
let e_dec = e - 1;
let o = e_dec * 8;
let crc = self.get_crc();
for i in 0..e {
vec.push((crc << ((e_dec - i) * 8) >> o) as u8).unwrap();
}
vec
}
pub fn get_crc_heapless_vec_be(&mut self) -> HeaplessVec<u8, U8> {
let mut vec = HeaplessVec::new();
let bits = match self {
CRC::CRCu8(crc) => f64::from(crc.bits),
CRC::CRCu16(crc) => f64::from(crc.bits),
CRC::CRCu32(crc) => f64::from(crc.bits),
CRC::CRCu64(crc) => f64::from(crc.bits),
};
let e = ((bits + 7f64) / 8f64) as u64;
let e_dec = e - 1;
let o = e_dec * 8;
let crc = self.get_crc();
for i in 0..e {
vec.push((crc << (i * 8) >> o) as u8).unwrap();
}
vec
}
}
impl CRC {
pub fn crc3gsm() -> CRC {
CRC::CRCu8(CRCu8::crc3gsm())
}
pub fn crc4itu() -> CRC {
CRC::CRCu8(CRCu8::crc4itu())
}
pub fn crc4interlaken() -> CRC {
CRC::CRCu8(CRCu8::crc4interlaken())
}
pub fn crc5epc() -> CRC {
CRC::CRCu8(CRCu8::crc5epc())
}
pub fn crc5itu() -> CRC {
CRC::CRCu8(CRCu8::crc5itu())
}
pub fn crc5usb() -> CRC {
CRC::CRCu8(CRCu8::crc5usb())
}
#[inline]
pub fn crc6cdma2000_a() -> CRC {
CRC::CRCu8(CRCu8::crc6cdma2000_a())
}
#[inline]
pub fn crc6cdma2000_b() -> CRC {
CRC::CRCu8(CRCu8::crc6cdma2000_b())
}
#[inline]
pub fn crc6darc() -> CRC {
CRC::CRCu8(CRCu8::crc6darc())
}
#[inline]
pub fn crc6gsm() -> CRC {
CRC::CRCu8(CRCu8::crc6gsm())
}
#[inline]
pub fn crc6itu() -> CRC {
CRC::CRCu8(CRCu8::crc6itu())
}
#[inline]
pub fn crc7() -> CRC {
CRC::CRCu8(CRCu8::crc7())
}
#[inline]
pub fn crc7umts() -> CRC {
CRC::CRCu8(CRCu8::crc7umts())
}
#[inline]
pub fn crc8() -> CRC {
CRC::CRCu8(CRCu8::crc8())
}
#[inline]
pub fn crc8cdma2000() -> CRC {
CRC::CRCu8(CRCu8::crc8cdma2000())
}
#[inline]
pub fn crc8darc() -> CRC {
CRC::CRCu8(CRCu8::crc8darc())
}
#[inline]
pub fn crc8dvb_s2() -> CRC {
CRC::CRCu8(CRCu8::crc8dvb_s2())
}
#[inline]
pub fn crc8ebu() -> CRC {
CRC::CRCu8(CRCu8::crc8ebu())
}
#[inline]
pub fn crc8icode() -> CRC {
CRC::CRCu8(CRCu8::crc8icode())
}
#[inline]
pub fn crc8itu() -> CRC {
CRC::CRCu8(CRCu8::crc8itu())
}
#[inline]
pub fn crc8maxim() -> CRC {
CRC::CRCu8(CRCu8::crc8maxim())
}
#[inline]
pub fn crc8rohc() -> CRC {
CRC::CRCu8(CRCu8::crc8rohc())
}
#[inline]
pub fn crc8wcdma() -> CRC {
CRC::CRCu8(CRCu8::crc8wcdma())
}
#[inline]
pub fn crc10() -> CRC {
CRC::CRCu16(CRCu16::crc10())
}
#[inline]
pub fn crc10cdma2000() -> CRC {
CRC::CRCu16(CRCu16::crc10cdma2000())
}
#[inline]
pub fn crc10gsm() -> CRC {
CRC::CRCu16(CRCu16::crc10gsm())
}
#[inline]
pub fn crc11() -> CRC {
CRC::CRCu16(CRCu16::crc11())
}
#[inline]
pub fn crc12() -> CRC {
CRC::CRCu16(CRCu16::crc12())
}
#[inline]
pub fn crc12cdma2000() -> CRC {
CRC::CRCu16(CRCu16::crc12cdma2000())
}
#[inline]
pub fn crc12gsm() -> CRC {
CRC::CRCu16(CRCu16::crc12gsm())
}
#[inline]
pub fn crc13bbc() -> CRC {
CRC::CRCu16(CRCu16::crc13bbc())
}
#[inline]
pub fn crc14darc() -> CRC {
CRC::CRCu16(CRCu16::crc14darc())
}
#[inline]
pub fn crc14gsm() -> CRC {
CRC::CRCu16(CRCu16::crc14gsm())
}
#[inline]
pub fn crc15can() -> CRC {
CRC::CRCu16(CRCu16::crc15can())
}
#[inline]
pub fn crc15mpt1327() -> CRC {
CRC::CRCu16(CRCu16::crc15mpt1327())
}
#[inline]
pub fn crc16() -> CRC {
CRC::CRCu16(CRCu16::crc16())
}
#[inline]
pub fn crc16ccitt_false() -> CRC {
CRC::CRCu16(CRCu16::crc16ccitt_false())
}
#[inline]
pub fn crc16aug_ccitt() -> CRC {
CRC::CRCu16(CRCu16::crc16aug_ccitt())
}
#[inline]
pub fn crc16buypass() -> CRC {
CRC::CRCu16(CRCu16::crc16buypass())
}
#[inline]
pub fn crc16cdma2000() -> CRC {
CRC::CRCu16(CRCu16::crc16cdma2000())
}
#[inline]
pub fn crc16dds_110() -> CRC {
CRC::CRCu16(CRCu16::crc16dds_110())
}
#[inline]
pub fn crc16dect_r() -> CRC {
CRC::CRCu16(CRCu16::crc16dect_r())
}
#[inline]
pub fn crc16dect_x() -> CRC {
CRC::CRCu16(CRCu16::crc16dect_x())
}
#[inline]
pub fn crc16dnp() -> CRC {
CRC::CRCu16(CRCu16::crc16dnp())
}
#[inline]
pub fn crc16en_13757() -> CRC {
CRC::CRCu16(CRCu16::crc16en_13757())
}
#[inline]
pub fn crc16genibus() -> CRC {
CRC::CRCu16(CRCu16::crc16genibus())
}
#[inline]
pub fn crc16maxim() -> CRC {
CRC::CRCu16(CRCu16::crc16maxim())
}
#[inline]
pub fn crc16mcrf4cc() -> CRC {
CRC::CRCu16(CRCu16::crc16mcrf4cc())
}
#[inline]
pub fn crc16riello() -> CRC {
CRC::CRCu16(CRCu16::crc16riello())
}
#[inline]
pub fn crc16t10_dif() -> CRC {
CRC::CRCu16(CRCu16::crc16t10_dif())
}
#[inline]
pub fn crc16teledisk() -> CRC {
CRC::CRCu16(CRCu16::crc16teledisk())
}
#[inline]
pub fn crc16tms13157() -> CRC {
CRC::CRCu16(CRCu16::crc16tms13157())
}
#[inline]
pub fn crc16usb() -> CRC {
CRC::CRCu16(CRCu16::crc16usb())
}
#[inline]
pub fn crc_a() -> CRC {
CRC::CRCu16(CRCu16::crc_a())
}
#[inline]
pub fn crc16kermit() -> CRC {
CRC::CRCu16(CRCu16::crc16kermit())
}
#[inline]
pub fn crc16modbus() -> CRC {
CRC::CRCu16(CRCu16::crc16modbus())
}
#[inline]
pub fn crc16_x25() -> CRC {
CRC::CRCu16(CRCu16::crc16_x25())
}
#[inline]
pub fn crc16xmodem() -> CRC {
CRC::CRCu16(CRCu16::crc16xmodem())
}
#[inline]
pub fn crc17can() -> CRC {
CRC::CRCu32(CRCu32::crc17can())
}
#[inline]
pub fn crc21can() -> CRC {
CRC::CRCu32(CRCu32::crc21can())
}
#[inline]
pub fn crc24() -> CRC {
CRC::CRCu32(CRCu32::crc24())
}
#[inline]
pub fn crc24ble() -> CRC {
CRC::CRCu32(CRCu32::crc24ble())
}
#[inline]
pub fn crc24flexray_a() -> CRC {
CRC::CRCu32(CRCu32::crc24flexray_a())
}
#[inline]
pub fn crc24flexray_b() -> CRC {
CRC::CRCu32(CRCu32::crc24flexray_b())
}
#[inline]
pub fn crc24lte_a() -> CRC {
CRC::CRCu32(CRCu32::crc24lte_a())
}
#[inline]
pub fn crc24lte_b() -> CRC {
CRC::CRCu32(CRCu32::crc24lte_b())
}
#[inline]
pub fn crc24os9() -> CRC {
CRC::CRCu32(CRCu32::crc24os9())
}
#[inline]
pub fn crc30cdma() -> CRC {
CRC::CRCu32(CRCu32::crc30cdma())
}
#[inline]
pub fn crc32() -> CRC {
CRC::CRCu32(CRCu32::crc32())
}
#[inline]
pub fn crc32mhash() -> CRC {
CRC::CRCu32(CRCu32::crc32mhash())
}
#[inline]
pub fn crc32bzip2() -> CRC {
CRC::CRCu32(CRCu32::crc32bzip2())
}
#[inline]
pub fn crc32c() -> CRC {
CRC::CRCu32(CRCu32::crc32c())
}
#[inline]
pub fn crc32d() -> CRC {
CRC::CRCu32(CRCu32::crc32d())
}
#[inline]
pub fn crc32mpeg2() -> CRC {
CRC::CRCu32(CRCu32::crc32mpeg2())
}
#[inline]
pub fn crc32posix() -> CRC {
CRC::CRCu32(CRCu32::crc32posix())
}
#[inline]
pub fn crc32q() -> CRC {
CRC::CRCu32(CRCu32::crc32q())
}
#[inline]
pub fn crc32jamcrc() -> CRC {
CRC::CRCu32(CRCu32::crc32jamcrc())
}
#[inline]
pub fn crc32xfer() -> CRC {
CRC::CRCu32(CRCu32::crc32xfer())
}
#[inline]
pub fn crc40gsm() -> CRC {
CRC::CRCu64(CRCu64::crc40gsm())
}
#[inline]
pub fn crc64() -> CRC {
CRC::CRCu64(CRCu64::crc64())
}
#[inline]
pub fn crc64iso() -> CRC {
CRC::CRCu64(CRCu64::crc64iso())
}
#[inline]
pub fn crc64we() -> CRC {
CRC::CRCu64(CRCu64::crc64we())
}
#[inline]
pub fn crc64jones() -> CRC {
CRC::CRCu64(CRCu64::crc64jones())
}
}