#crc #checksum #data-integrity

no-std crc8-rs

一个用于进行 8 位循环冗余校验的无堆栈 no_std 库

4 个稳定版本

1.1.1 2021 年 11 月 12 日
1.1.0 2021 年 3 月 18 日
1.0.1 2021 年 3 月 10 日

#486嵌入式开发

MIT 许可证

24KB
204

crc8-rs

注意:我强烈建议您使用 crc 包 而不是此包

crc8-rs 是 Rust 中 8 位循环冗余校验的最小化无堆栈 no_std 实现。这允许我们检查数据的完整性,因此主要用于在不可靠或嘈杂的连接中传输数据。例如,这包括与嵌入式系统和网络连接的连接。

请参阅文档

特性

此包提供处理 8 位系统中 CRC 的最小化函数。提供的函数包括 fetch_crc8has_valid_crc8insert_crc8。这应该使处理大多数常见的 CRC 场景变得简单。由于此包采用的最小化方法,二进制大小应保持较小。这对于嵌入式硬件特别合适。

使用方法

将此添加到项目的 Cargo.toml

[dependencies]
crc8-rs = "1.1"

通常有两种使用此包的方法。我们可以使用普通缓冲区或使用 struct 方法包装 CRC。让我们来看看两种方法。

使用普通缓冲区

在传输端,我们会有类似的代码如下。

use crc8_rs::{ has_valid_crc8, insert_crc8 };

// We are given a data buffer we would like to transfer
// It is important to leave a unused byte at the end for the CRC byte
let data: [u8; 256] = [
    // ...snip
];

// We can insert a CRC byte to the data buffer, this will be the last byte
// This time we use the generator polynomial of `0xD5`
let crc_data: [u8; 256] = insert_crc8(data, 0xD5);

// Now we are able to verify that the CRC is valid
assert!(has_valid_crc8(crc_data, 0xD5));

// Transfer the data...

然后在接收端,我们会有如下代码。

use crc8_rs::has_valid_crc8;

// We receive the CRCed data from some source
// This buffer has the CRC byte as the last byte
let crc_data: [u8; 256] = // ...snip

// Now we can conditionally unpack it and use the data
if has_valid_crc8(crc_data, 0xD5) {
    // The data is contained in the crc_data
    let data = crc_data;

    // ...snip
} else {
    panic!("CRC is invalid!")
}

包装 CRC

如果我们想从一些给定的数据中形成数据包,我们可能在传输数据时附加一个 CRC 字节来验证数据的完整性。

use crc8_rs::insert_crc8;

// Define a example packet structure
struct Packet {
    header:  [u8; 4],
    content: [u8; 247],
    footer:  [u8; 4],
}

impl Packet {
    fn to_data_buffer(&self) -> [u8; 256] {
        let mut data = [0; 256];

        // First we insert the packet data into the buffer
        for i in 0..4   { data[i]       = self.header[i] }
        for i in 0..247 { data[i + 4]   = self.content[i] }
        for i in 0..4   { data[i + 251] = self.footer[i] }

        // We use the generator polynomial `0xD5` here.
        insert_crc8(data, 0xD5)
    }
}

接收给定的缓冲区现在非常简单。

use crc8_rs::has_valid_crc8;

struct ReceivedPacket {
    header:  [u8; 4],
    content: [u8; 247],
    footer:  [u8; 4],
}

impl ReceivedPacket {
    fn receive(data: [u8; 256]) -> Option<ReceivedPacket> {
        // Before we construct the instance, we first check the CRC
        if has_valid_crc8(data, 0xD6) {
            Some(ReceivedPacket {
                // ...snip
            })
        } else {
            None
        }
    }
}

许可证

使用 MIT 许可证授权。

无运行时依赖