为什么我们在计算校验和时使用 1 的补码而不是 2 的补码

Why we use 1's complement instead of 2's complement when calculating checksums

在计算 UDP 校验和时,我知道我们对结果进行补充并使用它来检查错误。但是我不明白为什么我们用1的补码而不是2的补码(as shown here)。如果没有错误 1 ​​的补码结果 -1 (0xFFFF) 和 2 的补码结果 0 (0x0000).

为了检查传输是否正确,接收方的CPU必须首先否定结果然后查看ALU 的零标志。这需要 1 个额外的否定周期。如果使用 2 的补码,则只需查看零标志即可进行错误检查。

那是因为如果发件人使用 2 的补码可能会给你一个错误的结果 和接收机器有不同的字节顺序。

如果我们使用示例:

0000 1111 1110 0000 1111 0000 0001 0000

在小端机器上计算的带有 2 的补码的校验和为:

0000 0000 0001 0000

如果我们在大端机器上将原始数据添加到此校验和中,我们将得到:

0000 0000 1111 1111

这表明我们的校验和是错误的,尽管事实并非如此。然而,1 的补码结果与机器的字节顺序无关,所以如果我们用 1 的补码做同样的事情,我们的校验和将是:

0000 0000 0000 1111

当与数据一起添加时,我们将得到:

1111 1111 1111 1111

这允许短 UDP 校验和工作,而不需要发送方和接收方机器具有相同的字节顺序。