Skip to content

Commit

Permalink
First part of issue trifectatechfoundation#14
Browse files Browse the repository at this point in the history
Add a naive implementation of CRC-32 based
on the C code from the PNG specification.
  • Loading branch information
ahomescu committed Feb 7, 2024
1 parent fc8e11e commit 45e8aa3
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 0 deletions.
2 changes: 2 additions & 0 deletions zlib-rs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,5 @@ libc.workspace = true
[dev-dependencies]
libloading = "0.8.1"
libz-ng-sys = "1.1.12"
crc32fast = "1.3.2"
quickcheck = "1.0.3"
46 changes: 46 additions & 0 deletions zlib-rs/src/crc32.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
use std::sync::Once;

const LSB_POLY: u32 = 0xedb8_8320u32;
const START_CHECKSUM: u32 = 0xffff_ffffu32;
const FINAL_XOR: u32 = 0xffff_ffffu32;

// This could be auto-generated
static mut CRC_TABLE: [u32; 256] = [0; 256];
static CRC_TABLE_ONCE: Once = Once::new();

fn get_crc_table() -> &'static [u32] {
CRC_TABLE_ONCE.call_once(|| {
for i in 0..256u16 {
let mut c = u32::from(i);
for k in 0..8 {
if c & 1 != 0 {
c = LSB_POLY ^ (c >> 1);
} else {
c >>= 1;
}
}
unsafe { CRC_TABLE[usize::from(i)] = c; }
}
});
unsafe { &CRC_TABLE[..] }
}

fn naive_crc32(data: &[u8]) -> u32 {
let crc_table = get_crc_table();
let crc = data.iter().fold(START_CHECKSUM, |crc, val| {
let i = (crc as u8) ^ *val;
crc_table[usize::from(i)] ^ (crc >> 8)
});
crc ^ FINAL_XOR
}

#[cfg(test)]
mod test {
use super::*;

quickcheck::quickcheck! {
fn naive_is_crc32fast(v: Vec<u8>) -> bool {
naive_crc32(&v[..]) == crc32fast::hash(&v[..])
}
}
}
1 change: 1 addition & 0 deletions zlib-rs/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
mod adler32;
mod crc32;
pub mod allocate;
pub mod c_api;
pub mod deflate;
Expand Down

0 comments on commit 45e8aa3

Please sign in to comment.