在C/C++中,帧校验函数通常用于验证数据帧的完整性,常见的校验方式包括 CRC校验、Checksum校验、异或(XOR)校验 等。以下是几种典型的帧校验函数实现:
1. XOR(异或)校验
适用于简单的数据完整性检查,计算速度快但可靠性较低。
#include <stdint.h>
/**
* @brief XOR 帧校验
* @param data 待校验的数据缓冲区
* @param len 数据长度
* @return uint8_t 计算结果(0表示可能无错误)
*/
uint8_t XorCheck(const uint8_t* data, size_t len) {
uint8_t checksum = 0;
for (size_t i = 0; i < len; ++i) {
checksum ^= data[i];
}
return checksum;
}
特点
- ✅ 计算简单快速
- ❌ 抗干扰能力弱(交换字节顺序不影响结果)
2. Checksum(累加和)校验
比XOR稍强,但仍可能漏检某些错误。
#include <stdint.h>
/**
* @brief Checksum 累加和校验
* @param data 待校验的数据缓冲区
* @param len 数据长度
* @return uint16_t 计算结果(低8位或16位)
*/
uint16_t Checksum(const uint8_t* data, size_t len) {
uint16_t sum = 0;
for (size_t i = 0; i < len; ++i) {
sum += data[i];
}
return sum & 0xFFFF; // 取低16位(可改为&0xFF仅保留低8位)
}
特点
- ✅ 比XOR更可靠
- ❌ 仍可能漏检某些多字节错误
3. CRC(循环冗余校验)
工业级标准,广泛用于通信协议(如Modbus、CAN、TCP/IP等)。
(1) CRC-8 / CRC-16 / CRC-32实现示例
这里以 CRC-16/Modbus
(多项式 0x8005
)为例:
#include <stdint.h>
// CRC-16/Modbus查表法(推荐)
uint16_t Crc16Modbus(const uint8_t* data, size_t len) {
const uint16_t crc_table[256] = { /* ...预计算的CRC表... */ };
uint16_t crc = 0xFFFF;
for (size_t i = 0; i < len; ++i) {
crc = (crc >> 8) ^ crc_table[(crc ^ data[i]) & 0xFF];
}
return crc;
}
// (完整代码需包含预计算的CRC表)
(2) Online CRC计算工具
如果不想手动生成CRC表,可以使用在线工具自动生成: 🔗 Online CRC Calculator
特点
- ✅ 高可靠性(可检测单比特、双比特及突发错误)
- ❌ 计算复杂度较高
4. MD5/SHA哈希(高级完整性验证)
适用于需要高安全性的场景(如文件传输):
#include <openssl/md5.h> // OpenSSL库
void CalculateMD5(const uint8_t* data, size_t len, unsigned char md5_out[MD5_DIGEST_LENGTH]) {
MD5_CTX ctx;
MD5_Init(&ctx);
MD5_Update(&ctx, data, len);
MD5_Final(md5_out, &ctx);
}
⚠️需安装OpenSSL:
sudo apt-get install libssl-dev
如何选择合适的帧校验?
方法 | 速度 | 可靠性 | 适用场景 |
---|---|---|---|
XOR | ⚡极快 | ❌低 | 简单嵌入式设备 |
Checksum | ⚡快 | 🟡中 | UART串口通信 |
CRC | 🏃中等 | ✅高 | Modbus/CAN/Ethernet |
SHA/MD5 | 🐢慢 | 💯极高 | HTTPS/文件完整性验证 |
如果需要具体优化版本或特定协议的实现细节,可以进一步讨论!
内容由零声教学AI助手提供,问题来源于学员提问