Fletcher校验和:模255总和是否真的与一个补码和相同

时间:2018-03-06 16:59:22

标签: c checksum modulo uart ones-complement

我的问题背景简短: 我正在开发一个小型业余爱好项目,其微控制器通过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和一个补码和是相同的。这是真的吗?

  1. 对我来说有意义的是,使得补码校验和优越的进位可以在mod-255总和中与上面的补码加法器相同的方式工作。但是使用mod-255总和,你永远不会得到值0xFF(-0),只有0x00(+0)?
  2. 我猜mod操作符较慢(虽然它是线性的,所以你可以等待mod计算直到总和结束)。
  3. 一个不错的功能(当使用COBS时)是mod-255永远不会产生0x00校验字节,因为mod-255总和永远不会是0xFF(尽管即使在一个补码中它也很容易修复)上面的加法器)。
  4. 非常感谢您的时间!

    亲切的问候 /亨里克

1 个答案:

答案 0 :(得分:0)

否,Modulo 255不等于一个人的补语。我认为这里的混乱之处在于,弗莱彻的校验和同时使用255模加法,以一个人的补数为最后一步。另外,慢得多的模运算符可能只是对可能在asm中使用的ADC运算符建模。

一个人的补数是位的取反(按位非),通常作为计算的最终操作完成,称为“取一个人的补数”。这样做是为了优化验证过程,并将正确的结果强制为-0(或二进制格式为1111 1111)。它仅在使用补码算法的低级硬件上真正有用。如今,大多数其他人都使用二进制补码,因此要实现同一目的,除了位反转之外,还必须减去一个。

Modulo 255不同。目的可能是为“带进位添加”指令建模。如果Fletcher-16是在ADC指令的汇编中实现的,我不会感到惊讶。

基本上,而不只是忽略溢出,只要置位,它都会添加进位。 Modulo 255在这里达到相同的效果。通常这样做是为了以很少的成本提高校验和的错误检测质量。