我的问题背景简短: 我正在开发一个小型业余爱好项目,其微控制器通过UART与PC通信。现在我使用带有0x00数据包分隔符字节的COBS字节填充和一个简单的1字节校验和,它是一个运算和的二进制补码和一个补码和。我的补码校验和实现与Internet checksum非常相似(第7页。有趣的部分见下文)
// Fold 32-bit sum to 16 bits //
while (sum>>16)
sum = (sum & 0xffff) + (sum >> 16);
checksum = ~sum;
几天前,我发现了弗莱彻的校验和:
Fletcher article
Fletcher implementation
Fletcher Wikipedia
Fletcher Wiki页面的简短代码片段:
for( index = 0; index < count; ++index )
{
sum1 = (sum1 + data[index]) % 255;
sum2 = (sum2 + sum1) % 255;
}
return (sum2 << 8) | sum1;
我的问题:在上面的两篇文章中,他们都说Fletcher使用了&#34;补充[mod(255)]校验和&#34;好像mod-255和一个补码和是相同的。这是真的吗?
非常感谢您的时间!
亲切的问候 /亨里克
答案 0 :(得分:0)
否,Modulo 255不等于一个人的补语。我认为这里的混乱之处在于,弗莱彻的校验和同时使用255模加法和,以一个人的补数为最后一步。另外,慢得多的模运算符可能只是对可能在asm中使用的ADC
运算符建模。
一个人的补数是位的取反(按位非),通常作为计算的最终操作完成,称为“取一个人的补数”。这样做是为了优化验证过程,并将正确的结果强制为-0(或二进制格式为1111 1111)。它仅在使用补码算法的低级硬件上真正有用。如今,大多数其他人都使用二进制补码,因此要实现同一目的,除了位反转之外,还必须减去一个。
Modulo 255不同。目的可能是为“带进位添加”指令建模。如果Fletcher-16是在ADC指令的汇编中实现的,我不会感到惊讶。
基本上,而不只是忽略溢出,只要置位,它都会添加进位。 Modulo 255在这里达到相同的效果。通常这样做是为了以很少的成本提高校验和的错误检测质量。