-
Notifications
You must be signed in to change notification settings - Fork 48
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Standard CRC32 table based algorithm implemented. #32
Conversation
…in table generation and crc calculation. Maintained reverse compatability with v1.7.0 and added docs
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/ |
@mrhooray |
@mrhooray I completed updating all 3 CRC types. Now crc16, crc32, and crc64 are backwards compatible and can work normal or reflected. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks @CLomanno for updating the pr, left a few minor comments and gonna play around with it locally.
also added you as collaborator for this module since you care a lot about correctness, backward compatibility, users, etc
Cargo.toml
Outdated
@@ -12,6 +12,13 @@ license = "MIT OR Apache-2.0" | |||
[build-dependencies] | |||
build_const = "0.2" | |||
|
|||
#[dev-dependencies] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shall we remove unrelated changes or you want to move benchmarks to use criterion instead in this pr?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Criteron is nice, but we can use whatever you want. I left both in for you to choose
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cool, let's remove the commented code and revisit benchmark framework in separate pr?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed, Criterion adds a lot of bloat. I'll save the code for later in case it needs added back in
benches/bench.rs
Outdated
} | ||
|
||
/* | ||
#[macro_use] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed
src/crc16.rs
Outdated
/// | ||
/// *table:* Holds the table values based on the supplied polynomial for the fast CRC calculations | ||
/// | ||
/// *initial:* The initial inut value. AKA reflect_in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: input
instead of inut
, and a few other occurrences in this pr
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A lot of the comments were copy/pasted between crc16/32/64
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do you want to keep it, or it's actually a typo?
src/util.rs
Outdated
} | ||
|
||
/// Reflects the lease significant byte of a u32. | ||
pub fn reflect_long_32(input: u32) -> u32 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
have following 3 functions named consistently like reflect_byte_16/32/64
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed to reflect_value_16
etc.
src/util.rs
Outdated
} | ||
table | ||
} | ||
|
||
/// Reflects a value of a 16 bit number | ||
pub fn reflect_short(mut value: u16) -> u16 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
reflect_16/32/64
or something similar?
just to make things consistent with next set of 3 functions
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed to reflect_byte_16
etc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for the sudden influx of comments. I'm interested in seeing if I can replace code I've written with this crate, so I'd thought I'd voice my opinions 😄
src/crc16.rs
Outdated
for &i in bytes.iter() { | ||
value = table[((value as u8) ^ i) as usize] ^ (value >> 8) | ||
if true == rfl { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test for reflection should be hoisted outside the loop to avoid the needless conditional check for each byte. Also I feel like
if rfl {
}
is more idiomatic than
if true == rfl {
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updated to just if rfl {
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It makes sense to take it out of the update()
function. I couldn't cleanly get it out of make_table_crcXX()
src/crc16.rs
Outdated
} | ||
|
||
impl Digest { | ||
/// *Only works for reflected CRCs* |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have you taken a look at how these docs render? If you are intending for there to be a space between this and the next sentence I believe you'll a new line, else it might just render as a single paragraph
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right. Fixed
src/crc32.rs
Outdated
/// | ||
/// # Definitions | ||
/// | ||
/// *table:* Holds the table values based on the supplied polynomial for the fast CRC calculations |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You may have better luck with formatting with lists
- table: Holds the table values based on the supplied polynomial for the fast CRC calculations
- initial:
- reflect:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updated
src/util.rs
Outdated
pub fn make_table_crc16(poly: u16) -> [u16; 256] { | ||
/// Builds a CRC16 table using the standard or reflected CRC method | ||
/// If reflect==true, flip the individual byte bitwise, then flip the 32bit table value bitwise | ||
pub fn make_table_crc16(poly: u16, rfl: bool) -> [u16; 256] { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If in the rustdoc you mention the reflect
parameter, shouldn't the parameter be reflect: bool
instead of rfl: bool
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updated
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)
} |
@nickbabcock I like your speed improvement. I put it in! It also got rid of the |
thanks @CLomanno @nickbabcock |
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.