ironworks/sqpack/index/
crc.rs

1// Stolen and ported to rust from https://github.com/NotAdam/Lumina/blob/8abfa032fc0f47e79a58f7539dca2b23c96c66c8/src/Lumina/Misc/Crc32.cs
2
3const 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}