mint_cli/output/
checksum.rs1use crate::layout::settings::CrcData;
2
3pub fn calculate_crc(data: &[u8], crc_settings: &CrcData) -> u32 {
6 let mut crc = if crc_settings.ref_in {
8 crc_settings.start.reverse_bits()
9 } else {
10 crc_settings.start
11 };
12
13 let poly = if crc_settings.ref_in {
15 crc_settings.polynomial.reverse_bits()
16 } else {
17 crc_settings.polynomial
18 };
19
20 for &byte in data {
22 let idx = if crc_settings.ref_in {
23 (crc ^ (byte as u32)) & 0xFF
24 } else {
25 ((crc >> 24) ^ (byte as u32)) & 0xFF
26 };
27
28 let mut step = if crc_settings.ref_in { idx } else { idx << 24 };
30 if crc_settings.ref_in {
31 for _ in 0..8 {
32 step = (step >> 1) ^ ((step & 1) * poly);
33 }
34 } else {
35 for _ in 0..8 {
36 step = (step << 1) ^ (((step >> 31) & 1) * poly);
37 }
38 }
39
40 crc = if crc_settings.ref_in {
41 step ^ (crc >> 8)
42 } else {
43 step ^ (crc << 8)
44 };
45 }
46
47 if crc_settings.ref_in ^ crc_settings.ref_out {
49 crc = crc.reverse_bits();
50 }
51
52 crc ^ crc_settings.xor_out
53}
54
55#[cfg(test)]
56mod tests {
57 use super::*;
58 use crate::layout::settings::CrcArea;
59
60 #[test]
63 fn test_crc32_standard_test_vector() {
64 let crc_settings = CrcData {
65 polynomial: 0x04C11DB7,
66 start: 0xFFFF_FFFF,
67 xor_out: 0xFFFF_FFFF,
68 ref_in: true,
69 ref_out: true,
70 area: CrcArea::Data,
71 };
72
73 let test_str = b"123456789";
76 let result = calculate_crc(test_str, &crc_settings);
77 assert_eq!(
78 result, 0xCBF43926,
79 "Standard CRC32 test vector failed (expected 0xCBF43926 for \"123456789\")"
80 );
81
82 let simple_data = vec![0x01, 0x02, 0x03, 0x04];
84 let simple_result = calculate_crc(&simple_data, &crc_settings);
85 assert_eq!(simple_result, 0xB63CFBCD, "CRC32 for [1,2,3,4] failed");
86 }
87
88 #[test]
89 fn test_crc32_mpeg2_non_reflected_vector() {
90 let crc_settings = CrcData {
91 polynomial: 0x04C11DB7,
92 start: 0xFFFF_FFFF,
93 xor_out: 0x0000_0000,
94 ref_in: false,
95 ref_out: false,
96 area: CrcArea::Data,
97 };
98
99 let test_str = b"123456789";
101 let result = calculate_crc(test_str, &crc_settings);
102 assert_eq!(
103 result, 0x0376E6E7,
104 "CRC32/MPEG-2 test vector failed (expected 0x0376E6E7 for \"123456789\")"
105 );
106 }
107}