diff --git a/src/crc.rs b/src/crc.rs new file mode 100644 index 0000000..8103669 --- /dev/null +++ b/src/crc.rs @@ -0,0 +1,73 @@ +pub struct Crc8 { + table : [u8; 256] +} + +impl Crc8 { + pub fn create_msb(polynomial : u8) -> Crc8 { + let msbit : u8 = 0x80; + let mut t : u8 = msbit; + let mut tmp : u8; + let mut i : u32 = 1; + let mut idx : u8; + let mut table : [u8; 256] = [0; 256]; + + while i < 256 { + if t & msbit != 0 { tmp = polynomial; } else { tmp = 0; } + t = (t << 1) ^ tmp; + for j in 0..i { + idx = (i+j) as u8; + table[(idx) as usize] = table[j as usize] ^ t; + } + i *= 2; + } + + return Crc8{ table : table}; + } + + pub fn create_lsb(polynomial :u8) -> Crc8 { + let mut i :u32 = 0xff; + let mut j :u32; + let mut t :u8 = 1; + let mut tmp :u8; + let mut idx :u8; + let mut table : [u8; 256] = [0; 256]; + + while i != 0 { + if t & 1 != 0 { tmp = polynomial; } else { tmp = 0; } + t = (t >> 1) ^ tmp; + j = 0; + while j < 256 { + idx = (i+j) as u8; + table[idx as usize] = table[j as usize] ^ t; + j += 2 * i; + } + i >>= 1; + } + + return Crc8{ table : table }; + } + + /// Update CRC using previously calculated value and return new one. + pub fn update(&self, buffer : &[u8], crc: u8) -> u8 { + let mut crc_tmp = crc; + + for i in 0..buffer.len() { + crc_tmp = self.table[((crc_tmp ^ buffer[i])) as usize]; + } + return crc_tmp; + } + + /// Calculate crc8 with default presets compatible with defaults of mp_binary + /// package used in kotlin Divan interfaces (msb, polynomial=0xA7, this is + /// bluetooth presets btw). + pub fn calc(data: &[u8]) -> u8 { + let crc = Crc8::create_msb(0xA7); + crc.update(data, 0) + } +} + +#[test] +fn test_crc8() { + let a = [1,2,3,4,5]; + assert_eq!(134, Crc8::calc(&a)); +} \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index 510a6d0..6233b2f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -121,6 +121,7 @@ pub mod bipack; mod error; mod ser; mod de; +mod crc; #[cfg(test)] mod tests {