我已经根据在1-Wire中应用的dallas crc8编写的crc计算器进行了一些测试,它使用了0x8c poly。我正在测试它在15字节字符串上添加1,2和3位错误(也将错误添加到crc本身)。粘贴的实现无法识别2,2位错误和9位错误...
static inline uint8_t roll(char input_byte, uint8_t crc) {
for(uint8_t i = 8; i; i--, input_byte >>= 1) {
uint8_t result = (crc ^ input_byte) & 0x01;
crc >>= 1;
if(result) crc ^= 0x8C;
}
return crc;
};
static inline uint8_t compute(const uint8_t *input_byte, uint16_t length) {
uint8_t crc = 0;
for(uint16_t b = 0; b < length; b++)
crc = roll(input_byte[b], crc);
return crc;
};
摆弄代码我注意到删除&amp;无论数据具有什么值(尝试使用不同类型的字符串),0x01都会导致准确度大幅提高:
static inline uint8_t roll(char input_byte, uint8_t crc) {
for(uint8_t i = 8; i; i--, input_byte >>= 1) {
uint8_t result = crc ^ input_byte;
crc >>= 1;
if(result) crc ^= 0x8C;
}
return crc;
};
static inline uint8_t compute(const uint8_t *input_byte, uint16_t length) {
uint8_t crc = 0;
for(uint16_t b = 0; b < length; b++)
crc = roll(input_byte[b], crc);
return crc;
};
对于发布的修改,我得到的不是1,2或3位错误,对于我需要的范围(0-15个字符或0-120位)总是100%准确度
有人可以帮我理解这里发生的事情吗?
答案 0 :(得分:0)
我相信你的测试方法存在缺陷。根据我的测试,原始实现检测到所有1,2和3位错误,以及99.2%的4位错误。您建议的替代方案几乎总是生成完全相同的结果(0xf7
)。这是预料之中的,因为crc ^ input_byte
几乎总是非零。
因此,您的实施与(大部分时间)相同:
static inline uint8_t compute(const uint8_t *input_byte, uint16_t length) {
uint8_t crc = 0;
for (int i = 0; i < 15; i++) {
for (int j = 0; j < 8; j++) {
crc >>= 1;
crc ^= 0x8C;
}
}
return crc;
}
确实会生成值0xf7
。
我相信你的测试中的缺陷是假设crc匹配是一件好事。相反,如果原始字符串上的crc在注入位错误后与crc相同,则表示错误(crc生成器未检测到错误)。