为什么我们在计算校验和时使用 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 校验和工作,而不需要发送方和接收方机器具有相同的字节顺序。
在计算 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 校验和工作,而不需要发送方和接收方机器具有相同的字节顺序。