我已经在我写的一个基于达拉斯crc8的1-Wire应用的循环冗余校验计算器上做了一些测试,它使用0x8c poly。我正在测试它,在一个15字节的字符串上添加1,2和3个比特错误(也将比特错误添加到crc本身)。粘贴的实现无法识别2,2位错误和9,3位错误...
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;
};在修改代码时,我注意到删除& 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位错误,始终100%的准确性,我需要的范围是0-15个字符或0-120位
有没有人能帮我了解一下这里发生了什么?
发布于 2017-09-10 10:15:20
我认为你的测试方法有缺陷。根据我的测试,原始实现可以检测所有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生成器没有检测到错误)。
https://stackoverflow.com/questions/46136403
复制相似问题