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