1const fn table() -> [u32; 256] {
4 let mut t = [0u32; 256];
5 let mut i = 0;
6 while i < 256 {
7 let mut c = i as u32;
8 let mut k = 0;
9 while k < 8 {
10 c = if c & 1 != 0 {
11 0xEDB8_8320 ^ (c >> 1)
12 } else {
13 c >> 1
14 };
15 k += 1;
16 }
17 t[i] = c;
18 i += 1;
19 }
20 t
21}
22
23static TABLE: [u32; 256] = table();
24
25pub fn crc32(bytes: impl IntoIterator<Item = u8>) -> u32 {
27 !bytes.into_iter().fold(!0u32, |c, b| {
28 TABLE[((c ^ b as u32) & 0xFF) as usize] ^ (c >> 8)
29 })
30}
31
32pub fn crc32_raw(c: u32, bytes: &[u8]) -> u32 {
35 bytes.iter().fold(c, |c, &b| {
36 TABLE[((c ^ b as u32) & 0xFF) as usize] ^ (c >> 8)
37 })
38}
39
40pub fn type_id(class_name: &str) -> u32 {
42 crc32(class_name.encode_utf16().flat_map(u16::to_le_bytes))
43}
44
45#[cfg(test)]
46mod tests {
47 use super::*;
48
49 #[test]
50 fn known_vectors() {
51 assert_eq!(crc32(*b"123456789"), 0xCBF4_3926);
52 assert_eq!(type_id("ImageBuffer"), 0x84E6_F2DD);
53 assert_eq!(type_id("GraphicsMesh"), 0xE61C_2FFE);
54 assert_eq!(type_id("MaterialInstance"), 0x2EBE_ED54);
55 }
56}