73 lines
1.9 KiB
Rust
73 lines
1.9 KiB
Rust
|
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));
|
||
|
}
|