2

对于背景,我正在尝试计算存储在常量内存中的 IP 数据包的校验和(不能就地修改它)。在进行校验和之前,我应该假设数据包中现有的校验和为 0。与其将所有数据复制到临时缓冲区并存储 0,不如对整个数据包进行校验和,然后减去结果中的现有校验和。

为此,我正在寻找我在这里找到的减法的补码版本。不幸的是,如果我使用它,并从 0 中减去 0,我会得到 0x1111 而不是预期的 0:

  1. 将 0 转换为一个补码:[1111]
  2. 接下来,我们添加 0:[1111]
  3. 没有溢出位,所以我们完成了......

我本来希望 0 - 0 是 0——我错过了什么?

4

2 回答 2

1

你不需要减去。

如果校验和有效,计算整个数据包的校验和,包括校验和,应该给你 0。如果结果不为 0,则数据包已损坏。

这就是路由器验证校验和的方式。

于 2017-06-08T16:46:59.597 回答
0

我建议阅读有关 One's Complement 的本教程

https://courses.cs.vt.edu/csonline/NumberSystems/Lessons/SubtractionWithOnesComplement/index.html

我认为这很容易:

0000 - 0000 = 0000 + 1111 = 1111

由于最后一个1111是 One's Complement 形式,我们知道这是一个负数,因为有一个 Leading 1。最后的操作是一个的补码 ( 1111)。

最终答案是- 0000。如您所知,补码计算的缺点是有两种形式来表示 Zero 0

于 2017-06-08T19:19:35.010 回答