Checksum和Bitshift

时间:2014-07-10 08:06:42

标签: c++ checksum

我正在学习创建原始数据包并在this教程之后发送它。一切都有意义,直到我到达生成校验和的代码。

unsigned short csum (unsigned short *buf, int nwords)
{
  unsigned long sum;
  for (sum = 0; nwords > 0; nwords--)
    sum += *buf++;
  sum = (sum >> 16) + (sum & 0xffff);
  sum += (sum >> 16);
  return ~sum;
}

看起来他正在总结缓冲区中的所有单词。但是当我点击

  sum = (sum >> 16) + (sum & 0xffff);
  sum += (sum >> 16);

我完全迷失了。看起来他把所有的位都移位了,基本上丢弃除了进位之外的所有位,然后将它加回到原始总和中?为什么& 0xfff必要吗?毕竟,为什么再次添加进位?是因为可能会有第二次执行?

2 个答案:

答案 0 :(得分:4)

该行:

sum = (sum >> 16) + (sum & 0xffff);

在32位整数中添加左右16位字。它基本上将数字分成两半并将两半加在一起。 sum>> 16给你左半部分,sum& 0xffff给你右半部分。

然后当这些2加在一起时,它们可能会溢出。这一行:

sum += (sum >> 16);

将溢出添加回原始编号。

答案 1 :(得分:0)

计算的校验和是16位(unsigned short通常是16位),但变量sumunsigned long,因此可能是32位。

因此,操作sum >> 16捕获总和的高位字,所有单词总和超过16位的时间都可以保持。然后将其与sum & 0xffff混合,这只是总和中的低位字。

这样,总和的所有位都“折入”,以便它们对最终结果有贡献。