Maraiah/maraiah/cksum.rs

67 lines
1.2 KiB
Rust
Raw Normal View History

2019-03-21 16:58:30 -07:00
//! Checksum functions.
2019-02-08 21:08:53 -08:00
2019-04-03 11:16:47 -07:00
// Accumulator for CRC function.
2019-02-10 02:31:57 -08:00
fn crc_accum(a: u32, _: u32) -> u32
2019-02-08 21:08:53 -08:00
{
2019-07-05 20:21:11 -07:00
if a & 1 == 1 {
ISO_3309_POLYNOMIAL ^ a >> 1
} else {
a >> 1
}
2019-02-08 21:08:53 -08:00
}
2019-04-03 11:16:47 -07:00
// Initializes a CRC array.
// FIXME: use const fn when stabilized
2019-02-08 21:08:53 -08:00
fn crc_init() -> [u32; 256]
{
2019-07-05 20:21:11 -07:00
let mut t = [0; 256];
for (n, v) in t.iter_mut().enumerate() {
*v = (0..8).fold(n as u32, crc_accum);
}
t
2019-02-08 21:08:53 -08:00
}
/// Creates an ADLER32 of all bytes in `b`.
///
/// # Examples
///
/// ```
2019-06-13 18:09:07 -07:00
/// use maraiah::cksum::adler32;
///
/// assert_eq!(adler32(b"Lorem ipsum dolor sit amet"), 0x83D5_09C5);
/// ```
pub fn adler32(b: &[u8]) -> u32
{
2019-07-05 20:21:11 -07:00
let mut x = 1;
let mut y = 0;
2019-07-05 20:21:11 -07:00
for &z in b {
let z = u32::from(z);
x = (x + z) % ADLER32_MODULO;
y = (y + x) % ADLER32_MODULO;
}
2019-07-05 20:21:11 -07:00
(y << 16) | x
}
2019-03-12 13:28:08 -07:00
/// Creates a CRC-32 of all bytes in `b` with the starting sum `s`. The
/// polynomial used is the one from ISO-3309.
2019-03-04 18:14:09 -08:00
///
/// # Examples
///
/// ```
2019-06-13 18:09:07 -07:00
/// use maraiah::cksum::crc32;
2019-03-04 18:14:09 -08:00
///
/// assert_eq!(crc32(b"Lorem ipsum dolor sit amet", !0), 0x5F29_D461);
/// ```
2019-02-08 21:08:53 -08:00
pub fn crc32(b: &[u8], s: u32) -> u32
{
2019-07-05 20:21:11 -07:00
let t = crc_init();
!b.iter().fold(s, |a, &o| a >> 8 ^ t[usize::from(a as u8 ^ o)])
2019-02-08 21:08:53 -08:00
}
const ISO_3309_POLYNOMIAL: u32 = 0xEDB8_8320;
2019-03-22 18:55:13 -07:00
const ADLER32_MODULO: u32 = 0xFFF1;
2019-02-08 21:08:53 -08:00
// EOF