aboutsummaryrefslogtreecommitdiff
path: root/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib.rs')
-rw-r--r--src/lib.rs71
1 files changed, 64 insertions, 7 deletions
diff --git a/src/lib.rs b/src/lib.rs
index f147286..8c4f9a9 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,4 +1,20 @@
-//! ## Example
+//! Fast, SIMD-accelerated CRC32 (IEEE) checksum computation.
+//!
+//! ## Usage
+//!
+//! ### Simple usage
+//!
+//! For simple use-cases, you can call the [`hash()`] convenience function to
+//! directly compute the CRC32 checksum for a given byte slice:
+//!
+//! ```rust
+//! let checksum = crc32fast::hash(b"foo bar baz");
+//! ```
+//!
+//! ### Advanced usage
+//!
+//! For use-cases that require more flexibility or performance, for example when
+//! processing large amounts of data, you can create and manipulate a [`Hasher`]:
//!
//! ```rust
//! use crc32fast::Hasher;
@@ -15,7 +31,7 @@
//! - A fast baseline implementation which processes up to 16 bytes per iteration
//! - An optimized implementation for modern `x86` using `sse` and `pclmulqdq` instructions
//!
-//! Calling the `Hasher::new` constructor at runtime will perform a feature detection to select the most
+//! Calling the [`Hasher::new`] constructor at runtime will perform a feature detection to select the most
//! optimal implementation for the current CPU feature set.
#![cfg_attr(not(feature = "std"), no_std)]
@@ -43,6 +59,15 @@ mod combine;
mod specialized;
mod table;
+/// Computes the CRC32 hash of a byte slice.
+///
+/// Check out [`Hasher`] for more advanced use-cases.
+pub fn hash(buf: &[u8]) -> u32 {
+ let mut h = Hasher::new();
+ h.update(buf);
+ h.finalize()
+}
+
#[derive(Clone)]
enum State {
Baseline(baseline::State),
@@ -72,25 +97,35 @@ impl Hasher {
/// This works just like `Hasher::new`, except that it allows for an initial
/// CRC32 state to be passed in.
pub fn new_with_initial(init: u32) -> Self {
- Self::internal_new_specialized(init).unwrap_or_else(|| Self::internal_new_baseline(init))
+ Self::new_with_initial_len(init, 0)
+ }
+
+ /// Create a new `Hasher` with an initial CRC32 state.
+ ///
+ /// As `new_with_initial`, but also accepts a length (in bytes). The
+ /// resulting object can then be used with `combine` to compute `crc(a ||
+ /// b)` from `crc(a)`, `crc(b)`, and `len(b)`.
+ pub fn new_with_initial_len(init: u32, amount: u64) -> Self {
+ Self::internal_new_specialized(init, amount)
+ .unwrap_or_else(|| Self::internal_new_baseline(init, amount))
}
#[doc(hidden)]
// Internal-only API. Don't use.
- pub fn internal_new_baseline(init: u32) -> Self {
+ pub fn internal_new_baseline(init: u32, amount: u64) -> Self {
Hasher {
- amount: 0,
+ amount,
state: State::Baseline(baseline::State::new(init)),
}
}
#[doc(hidden)]
// Internal-only API. Don't use.
- pub fn internal_new_specialized(init: u32) -> Option<Self> {
+ pub fn internal_new_specialized(init: u32, amount: u64) -> Option<Self> {
{
if let Some(state) = specialized::State::new(init) {
return Some(Hasher {
- amount: 0,
+ amount,
state: State::Specialized(state),
});
}
@@ -174,5 +209,27 @@ mod test {
hash_a.finalize() == hash_c.finalize()
}
+
+ fn combine_from_len(bytes_1: Vec<u8>, bytes_2: Vec<u8>) -> bool {
+ let mut hash_a = Hasher::new();
+ hash_a.update(&bytes_1);
+ let a = hash_a.finalize();
+
+ let mut hash_b = Hasher::new();
+ hash_b.update(&bytes_2);
+ let b = hash_b.finalize();
+
+ let mut hash_ab = Hasher::new();
+ hash_ab.update(&bytes_1);
+ hash_ab.update(&bytes_2);
+ let ab = hash_ab.finalize();
+
+ let mut reconstructed = Hasher::new_with_initial_len(a, bytes_1.len() as u64);
+ let hash_b_reconstructed = Hasher::new_with_initial_len(b, bytes_2.len() as u64);
+
+ reconstructed.combine(&hash_b_reconstructed);
+
+ reconstructed.finalize() == ab
+ }
}
}