ironworks/sqpack/index/
crc.rs1const POLY: u32 = 0xEDB88320;
4
5const TABLE_SIZE: usize = 16 * 256;
6type Table = [u32; TABLE_SIZE];
7const TABLE: Table = build_table();
8
9const fn build_table() -> Table {
10 let mut table: Table = [0; TABLE_SIZE];
11
12 let mut i = 0;
13
14 while i < 256 {
15 let mut res = i as u32;
16
17 let mut t = 0;
18 while t < 16 {
19 let mut k = 0;
20 while k < 8 {
21 res = if (res & 1) == 1 {
22 POLY ^ (res >> 1)
23 } else {
24 res >> 1
25 };
26
27 k += 1;
28 }
29
30 table[((t * 256) + i)] = res;
31
32 t += 1;
33 }
34
35 i += 1;
36 }
37
38 table
39}
40
41pub fn crc32(bytes: &[u8]) -> u32 {
42 let mut working = u32::MAX;
43
44 let mut start = 0;
45 let mut end = bytes.len();
46
47 while end >= 16 {
48 let a = TABLE[(3 * 256) + bytes[start + 12] as usize]
49 ^ TABLE[(2 * 256) + bytes[start + 13] as usize]
50 ^ TABLE[256 + bytes[start + 14] as usize]
51 ^ TABLE[bytes[start + 15] as usize];
52
53 let b = TABLE[(7 * 256) + bytes[start + 8] as usize]
54 ^ TABLE[(6 * 256) + bytes[start + 9] as usize]
55 ^ TABLE[(5 * 256) + bytes[start + 10] as usize]
56 ^ TABLE[(4 * 256) + bytes[start + 11] as usize];
57
58 let c = TABLE[(11 * 256) + (bytes[start + 4] as usize)]
59 ^ TABLE[(10 * 256) + bytes[start + 5] as usize]
60 ^ TABLE[(9 * 256) + bytes[start + 6] as usize]
61 ^ TABLE[(8 * 256) + bytes[start + 7] as usize];
62
63 let d = TABLE[(15 * 256) + (working as u8 ^ bytes[start]) as usize]
64 ^ TABLE[(14 * 256) + ((working >> 8) as u8 ^ bytes[start + 1]) as usize]
65 ^ TABLE[(13 * 256) + ((working >> 16) as u8 ^ bytes[start + 2]) as usize]
66 ^ TABLE[(12 * 256) + ((working >> 24) as u8 ^ bytes[start + 3]) as usize];
67
68 working = d ^ c ^ b ^ a;
69 start += 16;
70 end -= 16;
71 }
72
73 for _ in 0..end {
74 working = TABLE[(working as u8 ^ bytes[start]) as usize] ^ working >> 8;
75 start += 1;
76 }
77
78 !(working ^ u32::MAX)
79}