crc32c/
lib.rs

1//! This crate provides the CRC-32-Castagnoli algorithm.
2//!
3//! It provides both a software implementation, and a hardware-optimized one for SSE 4.2.
4//!
5//! # Example
6//!
7//! ```rust
8//! let message = b"Hello world!";
9//!
10//! let crc = crc32c::crc32c(message);
11//!
12//! assert_eq!(crc, 0x7B_98_E7_51);
13//! ```
14//!
15//! # Enabling hardware acceleration
16//!
17//! If you compile your code with `-C target-features=+sse4.2`,
18//! then the hardware-optimized version will be compiled into the code.
19//!
20//! Otherwise, the crate will use `cpuid` at runtime to detect the
21//! running CPU's features, and enable the appropriate algorithm.
22
23mod combine;
24mod hasher;
25#[cfg(all(target_arch = "aarch64", armsimd))]
26mod hw_aarch64;
27#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
28mod hw_tables;
29#[cfg(target_arch = "x86_64")]
30mod hw_x86_64;
31mod io;
32mod sw;
33mod util;
34
35pub use hasher::Crc32cHasher;
36
37pub use io::{Crc32cReader, Crc32cWriter};
38
39/// Computes the CRC for the data payload.
40///
41/// Equivalent to calling `crc32c_append(0, data)`.
42#[inline]
43pub fn crc32c(data: &[u8]) -> u32 {
44    crc32c_append(0, data)
45}
46
47/// Computes the CRC for the data payload, starting with a previous CRC value.
48#[inline]
49pub fn crc32c_append(crc: u32, data: &[u8]) -> u32 {
50    #[cfg(target_arch = "x86_64")]
51    {
52        if is_x86_feature_detected!("sse4.2") {
53            return unsafe { hw_x86_64::crc32c(crc, data) };
54        }
55    }
56
57    #[cfg(all(target_arch = "aarch64", armsimd))]
58    {
59        if std::arch::is_aarch64_feature_detected!("crc") {
60            return unsafe { hw_aarch64::crc32c(crc, data) };
61        }
62    }
63
64    sw::crc32c(crc, data)
65}
66
67/// Computes the "combined" value of two CRC32c values. Specifically, given two byte streams A and
68/// B and their CRC32c check values crc32c(A) and crc32c(B), this function calculates crc32c(AB)
69/// using only crc32c(A), crc32c(B), and the length of B.
70#[inline]
71pub fn crc32c_combine(crc1: u32, crc2: u32, len2: usize) -> u32 {
72    combine::crc32c_combine(crc1, crc2, len2)
73}