Skip to main content

wowlab_parsers/parsers/parcel/
crc32.rs

1//! CRC-32 helper (IEEE 802.3 / zlib polynomial `0xEDB88320`, per SPEC ยง3).
2
3use crc32fast::Hasher;
4
5pub(super) fn crc32_hex8(bytes: &[u8]) -> String {
6    let mut hasher = Hasher::new();
7
8    hasher.update(bytes);
9    let crc = hasher.finalize();
10
11    format!("{crc:08x}")
12}
13
14pub(super) fn is_checksum_token(s: &str) -> bool {
15    const CHECKSUM_LEN: usize = 8;
16
17    s.len() == CHECKSUM_LEN && s.bytes().all(|b| matches!(b, b'0'..=b'9' | b'a'..=b'f'))
18}
19
20#[cfg(test)]
21mod tests {
22    use googletest::prelude::*;
23
24    use super::*;
25
26    #[gtest]
27    fn spec_reference_vectors() -> Result<()> {
28        verify_that!(crc32_hex8(b""), eq("00000000"))?;
29        verify_that!(crc32_hex8(b"hello"), eq("3610a686"))?;
30        verify_that!(crc32_hex8(b"123456789"), eq("cbf43926"))?;
31
32        Ok(())
33    }
34
35    #[gtest]
36    fn checksum_token_validation() -> Result<()> {
37        verify_true!(is_checksum_token("00000000"))?;
38        verify_true!(is_checksum_token("3610a686"))?;
39        verify_true!(is_checksum_token("cbf43926"))?;
40        verify_false!(is_checksum_token("DEADBEEF"))?;
41        verify_false!(is_checksum_token("3610a68"))?;
42        verify_false!(is_checksum_token("3610a6868"))?;
43        verify_false!(is_checksum_token("3610a68g"))?;
44        verify_false!(is_checksum_token(""))?;
45
46        Ok(())
47    }
48}