1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
pub fn calculate_crc5(data: &[u8], poly: u8, init: u8, ref_in: bool, ref_out: bool, xor_out: u8) -> u8 { let mut crc = init; for d in data.iter() { let c = if ref_in { (*d).reverse_bits() } else { *d }; let mut i = 0x80; while i > 0 { let mut bit = (crc & 0x10) != 0; if (c & i) != 0 { bit = !bit; } crc <<= 1; if bit { crc ^= poly; } i >>= 1; } crc &= 0x1f; } if ref_out { crc = crc.reverse_bits() >> 3; } crc ^ xor_out } pub fn crc5(data: &[u8]) -> u8 { calculate_crc5(data, 0x5, 0x1f, true, true, 0x1f) } #[cfg(test)] mod tests { use super::*; fn check_sequence() -> Vec<u8> { "123456789".to_owned().into_bytes() } fn check_sequence_long() -> Vec<u8> { "helloworldchris!".to_owned().into_bytes() } #[test] fn test_crc5() { assert_eq!(crc5(&check_sequence()), 0x19); } #[test] fn test_crc5_long() { assert_eq!(crc5(&check_sequence_long()), 0xa); } #[test] fn test_crc5_long_long() { let mut data = check_sequence_long(); data.append(&mut check_sequence_long()); assert_eq!(crc5(&data), 0x1b); } #[test] fn test_crc5_long_long_long() { let mut data = check_sequence_long(); data.append(&mut check_sequence_long()); data.append(&mut check_sequence_long()); assert_eq!(crc5(&data), 0xc); } }