From e24e11188ea7e70762065ca9531fe1e47bfc362f Mon Sep 17 00:00:00 2001 From: Jonathan Strong Date: Wed, 6 Sep 2023 13:45:54 -0400 Subject: [PATCH] add docs and tests for `crc32_seed` --- src/lib.rs | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index be12277..7572664 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -48,6 +48,40 @@ pub const fn crc32(buf: &[u8]) -> u32 { crc32_seed(buf, 0) } +/// Calculate crc32 checksum, using provided `seed` as the initial state, instead of the +/// default initial state of `0u32`. +/// +/// # Examples +/// +/// Calculating the checksum from several parts of a larger input: +/// +/// ``` +/// const BYTES: &[u8] = "The quick brown fox jumps over the lazy dog".as_bytes(); +/// +/// let mut cksum = 0u32; +/// +/// cksum = const_crc32::crc32_seed(&BYTES[0..10], cksum); +/// cksum = const_crc32::crc32_seed(&BYTES[10..15], cksum); +/// cksum = const_crc32::crc32_seed(&BYTES[15..], cksum); +/// +/// assert_eq!(cksum, const_crc32::crc32(BYTES)); +/// ``` +/// +/// Using separate seeds for different kinds of data, to produce different checksums depending +/// on what kind of data the bytes represent: +/// +/// ``` +/// const THING_ONE_SEED: u32 = 0xdeadbeef_u32; +/// const THING_TWO_SEED: u32 = 0xbaaaaaad_u32; +/// +/// let thing_one_bytes = "bump! thump!".as_bytes(); +/// let thing_two_bytes = "thump! bump!".as_bytes(); +/// +/// let thing_one_cksum = const_crc32::crc32_seed(thing_one_bytes, THING_ONE_SEED); +/// let thing_two_cksum = const_crc32::crc32_seed(thing_two_bytes, THING_TWO_SEED); +/// +/// assert_ne!(thing_one_cksum, thing_two_cksum); +/// ``` #[inline] pub const fn crc32_seed(buf: &[u8], seed: u32) -> u32 { let mut out = !seed; @@ -94,6 +128,28 @@ mod tests { assert_eq!(crc32(BYTES), crc32fast::hash(BYTES)); } + #[test] + fn use_seed_to_checksum_from_partial_inputs() { + const BYTES: &[u8] = "The quick brown fox jumps over the lazy dog".as_bytes(); + let mut cksum = crc32(&BYTES[0..10]); + cksum = crc32_seed(&BYTES[10..], cksum); + assert_eq!(cksum, crc32(BYTES)); + } + + #[test] + fn use_seed_to_checksum_from_many_chunks() { + let mut buf = [0u8; 1024]; + let mut rng = thread_rng(); + rng.fill(&mut buf[..]); + + let mut cksum = 0; + for chunk in buf[..].chunks(7) { + cksum = crc32_seed(chunk, cksum); + } + + assert_eq!(cksum, crc32(&buf[..])); + } + #[test] fn check_random_inputs_against_crc32_fast() { const N_ITER: usize = 100;