1#[must_use]
9pub fn get_u64(bytes: &[u8], offset: usize) -> u64 {
10 let mut raw = [0u8; 8];
11 raw.copy_from_slice(&bytes[offset..offset + 8]);
12 u64::from_le_bytes(raw)
13}
14
15pub fn put_u64(bytes: &mut [u8], offset: usize, value: u64) {
17 bytes[offset..offset + 8].copy_from_slice(&value.to_le_bytes());
18}
19
20#[must_use]
22pub fn get_u32(bytes: &[u8], offset: usize) -> u32 {
23 let mut raw = [0u8; 4];
24 raw.copy_from_slice(&bytes[offset..offset + 4]);
25 u32::from_le_bytes(raw)
26}
27
28pub fn put_u32(bytes: &mut [u8], offset: usize, value: u32) {
30 bytes[offset..offset + 4].copy_from_slice(&value.to_le_bytes());
31}
32
33#[must_use]
35pub fn get_i64(bytes: &[u8], offset: usize) -> i64 {
36 get_u64(bytes, offset) as i64
37}
38
39pub fn put_i64(bytes: &mut [u8], offset: usize, value: i64) {
41 put_u64(bytes, offset, value as u64);
42}
43
44const fn crc32_table() -> [u32; 256] {
45 let mut table = [0u32; 256];
46 let mut index = 0;
47 while index < 256 {
48 let mut crc = index as u32;
49 let mut bit = 0;
50 while bit < 8 {
51 crc = if crc & 1 == 1 {
52 (crc >> 1) ^ 0xEDB8_8320
53 } else {
54 crc >> 1
55 };
56 bit += 1;
57 }
58 table[index] = crc;
59 index += 1;
60 }
61 table
62}
63
64static CRC32_TABLE: [u32; 256] = crc32_table();
65
66#[must_use]
68pub fn crc32(bytes: &[u8]) -> u32 {
69 crc32_update(0, bytes)
70}
71
72#[must_use]
74pub fn crc32_update(crc: u32, bytes: &[u8]) -> u32 {
75 let mut value = !crc;
76 for &byte in bytes {
77 value = CRC32_TABLE[((value ^ u32::from(byte)) & 0xFF) as usize] ^ (value >> 8);
78 }
79 !value
80}
81
82#[cfg(test)]
83mod tests {
84 use super::*;
85
86 #[test]
87 fn crc32_matches_reference_vector() {
88 assert_eq!(crc32(b"123456789"), 0xCBF4_3926);
89 assert_eq!(crc32_update(crc32(b"1234"), b"56789"), 0xCBF4_3926);
90 }
91
92 #[test]
93 fn integers_round_trip() {
94 let mut bytes = [0u8; 16];
95 put_u64(&mut bytes, 0, 0x0102_0304_0506_0708);
96 put_u32(&mut bytes, 8, 0xAABB_CCDD);
97 put_i64(&mut bytes, 8, -5);
98 assert_eq!(get_u64(&bytes, 0), 0x0102_0304_0506_0708);
99 assert_eq!(bytes[0], 0x08);
100 assert_eq!(get_i64(&bytes, 8), -5);
101 put_u32(&mut bytes, 12, 7);
102 assert_eq!(get_u32(&bytes, 12), 7);
103 }
104}