【问题标题】:Checksum and Bitshift校验和和位移
【发布时间】:2014-08-31 12:34:16
【问题描述】:

我正在学习创建一个原始数据包并按照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 是必要的?毕竟,为什么要再次添加执行位?是因为可能会有第二次执行吗?

【问题讨论】:

  • 大脑显然停止工作了(X

标签: c++ checksum


【解决方案1】:

行:

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

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

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

sum += (sum >> 16);

将溢出添加回原始数字。

【讨论】:

    【解决方案2】:

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

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

    这样,总和的所有位都被“折叠”,因此它们对最终结果有贡献。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-06-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多