2023-08-06 08:25:04 -04:00
|
|
|
// SPDX-FileCopyrightText: 2023 Joshua Goins <josh@redstrate.com>
|
|
|
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
|
2022-12-17 08:23:19 -05:00
|
|
|
pub struct Jamcrc {
|
2022-10-25 13:02:06 -04:00
|
|
|
table: [u32; 256],
|
2022-10-24 16:49:06 -04:00
|
|
|
}
|
|
|
|
|
2022-12-17 08:23:19 -05:00
|
|
|
impl Jamcrc {
|
2022-10-24 16:49:06 -04:00
|
|
|
pub(crate) const fn new() -> Self {
|
|
|
|
let mut table: [u32; 256] = [0u32; 256];
|
|
|
|
|
|
|
|
let polynomial: u32 = 0xEDB88320;
|
|
|
|
let mut i = 0;
|
|
|
|
while i < table.len() {
|
|
|
|
let mut c: u32 = i as u32;
|
|
|
|
let mut j = 0;
|
|
|
|
while j < 8 {
|
|
|
|
if (c & 1u32) == 1u32 {
|
|
|
|
c = polynomial ^ (c >> 1);
|
|
|
|
} else {
|
|
|
|
c >>= 1;
|
|
|
|
}
|
|
|
|
j += 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
table[i] = c;
|
|
|
|
i += 1;
|
|
|
|
}
|
|
|
|
|
2022-10-25 13:02:06 -04:00
|
|
|
Self { table }
|
2022-10-24 16:49:06 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) fn checksum(&self, bytes: &[u8]) -> u32 {
|
2022-10-25 13:02:06 -04:00
|
|
|
let mut c: u32 = 0xFFFFFFFF;
|
2022-10-24 16:49:06 -04:00
|
|
|
for byte in bytes {
|
|
|
|
c = self.table[((c ^ *byte as u32) & 0xFF) as usize] ^ (c >> 8);
|
|
|
|
}
|
|
|
|
|
|
|
|
!(c ^ 0xFFFFFFFF)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
|
|
|
use super::*;
|
|
|
|
|
|
|
|
#[test]
|
2022-12-17 08:23:19 -05:00
|
|
|
fn check_library() {
|
2022-10-24 16:49:06 -04:00
|
|
|
use crc::{Crc, CRC_32_JAMCRC};
|
|
|
|
|
|
|
|
const JAMCR: Crc<u32> = Crc::<u32>::new(&CRC_32_JAMCRC);
|
|
|
|
|
2022-10-25 13:02:06 -04:00
|
|
|
let bytes: [u8; 9] = [1, 1, 2, 4, 5, 6, 12, 12, 12];
|
2022-10-24 16:49:06 -04:00
|
|
|
|
2022-12-17 08:23:19 -05:00
|
|
|
const CRC: Jamcrc = Jamcrc::new();
|
2022-10-24 16:49:06 -04:00
|
|
|
|
2022-12-17 08:23:19 -05:00
|
|
|
assert_eq!(JAMCR.checksum(&bytes), CRC.checksum(&bytes))
|
2022-10-24 16:49:06 -04:00
|
|
|
}
|
2022-10-25 13:02:06 -04:00
|
|
|
}
|