工作原理
CRC-16 Modbus校验的工作原理基于一个简单的原理:对数据进行某种形式的加工,然后将结果(称为“校验和”)附加到数据上。接收方可以通过对接收到的数据执行相同的加工操作,并比较结果和附加的校验和,来检测数据是否在传输过程中被更改。
具体来说,CRC-16 Modbus校验的计算过程如下:
- 初始化一个16位的CRC值为0xFFFF。
- 遍历数据中的每一个字节,并将其与当前的CRC值进行异或操作。
- 对于每一个位,如果最低位(LSB)被设置了,那么就向右移位并与0xA001进行异或操作。如果LSB没有被设置,那么就只进行向右移位操作。
- 重复步骤2和3,直到处理完所有的数据。
返回最后得到的CRC值。
C-demo
#include <stdint.h>
uint16_t crc16_modbus(uint8_t *data, uint16_t length) {
uint16_t crc = 0xFFFF;
for (uint16_t pos = 0; pos < length; pos++) {
crc ^= (uint16_t)data[pos];
for (int i = 8; i != 0; i--) {
if ((crc & 0x0001) != 0) {
crc >>= 1;
crc ^= 0xA001;
}
else
crc >>= 1;
}
}
return crc;
}
C++ -demo
#include <cstdint>
#include <vector>
class CRC16Modbus {
public:
static uint16_t calculate(const std::vector<uint8_t>& data) {
uint16_t crc = 0xFFFF;
for (const auto& byte : data) {
crc ^= static_cast<uint16_t>(byte);
for (int i = 0; i < 8; i++) {
if ((crc & 0x0001) != 0) {
crc >>= 1;
crc ^= 0xA001;
} else {
crc >>= 1;
}
}
}
return crc;
}
};
python-demo
def crc16_modbus(data):
crc = 0xFFFF
for byte in data:
crc ^= byte
for _ in range(8):
if crc & 0x0001:
crc >>= 1
crc ^= 0xA001
else:
crc >>= 1
return crc