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

问题描述 投票:2回答:1

我的问题背景很短:我正在用一个微控制器通过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和一个补码和相同。是真的吗

  1. 对我来说,使一个人的补码校验和优越的进位比上面一个人的补码加法器在mod-255总和中的工作方式几乎相同。但是,使用mod-255的总和,您将永远无法获得值0xFF(-0),只有0x00(+0)吗?
  2. 我猜想mod运算符比较慢(尽管它是线性的,所以您可以等待mod-计算直到总和结束)。
  3. 一个不错的功能(当使用COBS时,是因为mod-255的总和永远不能为0xFF,因此mod-255永远不会产生0x00校验字节(尽管即使在上面的补码加法器中也很容易固定)。

非常感谢您的宝贵时间!

亲切的问候/ / Henrik

c checksum modulo uart ones-complement
1个回答
0
投票

否,Modulo 255不等于一个人的补语。我认为这里的困惑在于,弗莱彻的校验和利用255的加法运算符[[]]将一个人的补数作为最后一步。同样,慢得多的模运算符可能只是对可能在asm中使用的ADC运算符进行建模。一个人的补数是位的取反(按位非),通常作为计算的最终操作完成,称为“取一个人的补数”。这样做是为了优化验证过程,并将正确的结果强制为-0(或二进制格式为1111 1111)。它仅在使用补码算法的低级硬件上真正有用。如今,大多数其他人都使用二进制补码,因此要实现同一目的,除了位反转之外,您还必须减去一个。

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

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

© www.soinside.com 2019 - 2024. All rights reserved.