mrhooray / crc-rs

Rust implementation of CRC(16, 32, 64) with support of various standards
Apache License 2.0
191 stars 49 forks source link

Standard CRC32 table based algorithm implemented. #32

Closed CLomanno closed 6 years ago

CLomanno commented 6 years ago

I had to redefine the polys and expected CRCs for everything in CRC32. However I modified the functions in crc32 so they are all backwards compatible.

The new function new_with_initial_and_final() allows you to generate a reflected table with a custom initial and final XOR value.

@mrhooray Sorry, this is my first pull request and I didn't add a reviewer, assignee, or label.

CLomanno commented 6 years ago

I found the default values for various 32bit crc standards here: https://en.wikipedia.org/wiki/Cyclic_redundancy_check#Polynomial_representations_of_cyclic_redundancy_checks

Verified the correct crc values here: http://crccalc.com/

CLomanno commented 6 years ago

@mrhooray Sorry, this is my first pull request and I didn't add a reviewer, assignee, or label.

CLomanno commented 6 years ago

@mrhooray I completed updating all 3 CRC types. Now crc16, crc32, and crc64 are backwards compatible and can work normal or reflected.

nickbabcock commented 6 years ago

As a side note, I benchmarked this impl against:

pub fn calc_crc(data: &[u8]) -> u32 {
    !data.iter().fold(!0xefcb_f201, |acc, &x| {
        (acc << 8) ^ (TABLE[((u32::from(x)) ^ (acc >> 24)) as usize])
    })
}

Both produce the same output (:+1:), but this PR is 10-15% slower.

For reference, I wrote:

lazy_static! {
    static ref TABLE: [u32; 256] = make_table(0x04c11db7, false);
}

pub fn calc_crc(data: &[u8]) -> u32 {
    !update(!0xefcb_f201, &TABLE, data, false)
}
CLomanno commented 6 years ago

@nickbabcock I like your speed improvement. I put it in! It also got rid of the if rfl { check per iteration

mrhooray commented 6 years ago

thanks @CLomanno @nickbabcock will update readme etc and release