jiff/shared/crc32/
mod.rs

1use self::table::{TABLE, TABLE16};
2
3mod table;
4
5/// Returns the "masked" CRC32 checksum of the slice using the Castagnoli
6/// polynomial.
7///
8/// This "masked" checksum is the same one used by the Snappy frame format.
9/// Masking is supposed to make the checksum robust with respect to data that
10/// contains the checksum itself.
11pub(crate) fn sum(buf: &[u8]) -> u32 {
12    let sum = slice16(0, buf);
13    (sum.wrapping_shr(15) | sum.wrapping_shl(17)).wrapping_add(0xA282EAD8)
14}
15
16/// Returns the CRC32 checksum of `buf` using the Castagnoli polynomial.
17///
18/// This computes the checksum by looking at 16 bytes from the given slice
19/// per iteration.
20fn slice16(prev: u32, mut buf: &[u8]) -> u32 {
21    let mut crc: u32 = !prev;
22    while buf.len() >= 16 {
23        crc ^= u32::from_le_bytes(buf[..4].try_into().unwrap());
24        crc = TABLE16[0][usize::from(buf[15])]
25            ^ TABLE16[1][usize::from(buf[14])]
26            ^ TABLE16[2][usize::from(buf[13])]
27            ^ TABLE16[3][usize::from(buf[12])]
28            ^ TABLE16[4][usize::from(buf[11])]
29            ^ TABLE16[5][usize::from(buf[10])]
30            ^ TABLE16[6][usize::from(buf[9])]
31            ^ TABLE16[7][usize::from(buf[8])]
32            ^ TABLE16[8][usize::from(buf[7])]
33            ^ TABLE16[9][usize::from(buf[6])]
34            ^ TABLE16[10][usize::from(buf[5])]
35            ^ TABLE16[11][usize::from(buf[4])]
36            ^ TABLE16[12][usize::from((crc >> 24) as u8)]
37            ^ TABLE16[13][usize::from((crc >> 16) as u8)]
38            ^ TABLE16[14][usize::from((crc >> 8) as u8)]
39            ^ TABLE16[15][usize::from((crc) as u8)];
40        buf = &buf[16..];
41    }
42    for &b in buf {
43        crc = TABLE[usize::from((crc as u8) ^ b)] ^ (crc >> 8);
44    }
45    !crc
46}