我对如何计算互联网校验和有一些疑问。我从书中找不到任何好的解释,所以我在这里问。我不确定这是否是正确的地方,所以如果我在错误的地方询问,我很抱歉。
如果你看下面的例子。 发送以下两条消息:10101001和00111001.校验和以1的补码计算。到目前为止我明白了。但总和如何计算?起初我以为它可能是XOR,但似乎并非如此。
10101001
00111001
--------
Sum 11100010
Checksum: 00011101
然后当他们计算出msg是否正常时。又一次如何计算总和?
10101001
00111001
00011101
--------
Sum 11111111
Complement 00000000 means that the pattern is O.K.
答案 0 :(得分:8)
它使用加法,因此名称为“sum”。 10101001 + 00111001 = 11100010。
例如:
+------------+-----+----+----+----+---+---+---+---+--------+
| bin value | 128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 | result |
+------------+-----+----+----+----+---+---+---+---+--------+
| value 1 | 1 | 0 | 1 | 0 | 1 | 0 | 0 | 1 | 169 |
| value 2 | 0 | 0 | 1 | 1 | 1 | 0 | 0 | 1 | 57 |
| sum/result | 1 | 1 | 1 | 0 | 0 | 0 | 1 | 0 | 226 |
+------------+-----+----+----+----+---+---+---+---+--------+
答案 1 :(得分:8)
如果通过互联网校验和,你的意思是TCP Checksum有一个很好的探索here甚至一些code。
当你计算校验和时,记住它不仅仅是数据的函数,而且还有“伪头”,它将源IP,目的IP,协议和TCP数据包的长度放入数据中。校验和。这将tcp元数据与IP头中的某些数据联系起来。
TCP/IP Illustrated Vol 1是一个很好的参考,并详细解释了这一点。
答案 2 :(得分:2)
互联网校验和的计算使用一个补码算法。考虑校验和的数据是8位整数的序列。首先,您需要使用补码算法添加它们并获取结果的补码。
注意:当添加数字补码算术时,需要将MSB的残留添加到结果中。考虑例如,添加3(0011)和5(0101)。
3' - > 1100 5' - &GT 1010 0110携带1 因此,我们有,0111(1的补码表示-8)。
校验和是上一步获得的结果的1的补码。因此,我们有1000.如果不存在任何进位,我们只是补充在求和阶段获得的结果。
答案 3 :(得分:0)
通过对段中的所有16位字进行求和,在发送端创建UDP校验和,任何溢出被包围,然后执行1的补码,并将结果添加到校验和字段在细分市场内。 在接收方,如果结果是1111 1111 1111 1111,则添加数据包内的所有单词并在其上添加校验和,然后该段有效,否则该段有错误。 〔实施例: 0110 0110 0110 0000 0101 0101 0101 0101
1 0100 1010 1100 0001 //有一个溢出,所以我们把它包起来,意味着将它添加到总和中 总和= 0100 1010 1100 0010 现在让我们来看看1&1的补充 checksum = 1011 0101 0011 1101
在接收器处计算总和,然后将其添加到校验和中 0100 1010 1100 0010
1111 1111 1111 1111 //显然这应该是答案,如果不是则会出现错误 参考文献:计算机网络自上而下的方法[Ross-kurose]
答案 4 :(得分:0)
这是一个完整示例,其中包含IPv4数据包的真实标头。
这些是数据包头的20个字节:
45 00 00 34 5F 7C 40 00 40 06 [00 00] C0 A8 B2 14 C6 FC CE 19
发件人尚未计算校验和。方括号中的两个字节是校验和所在的位置。校验和的值最初设置为零。
我们可以在头脑中将此头分成10个16位值的序列:0x4500、0x0034、0x5F7C等。
让我们看看数据包的发送方如何计算标头校验和:
bc <<< 'obase=16;ibase=16;4500 + 0034 + 5F7C + 4000 + 4006 + 0000 + C0A8 + B214 + C6FC + CE19'
bc <<< 'obase=16;ibase=16;2C87 + 4'
最后,将校验和插入标头:
45 00 00 34 5F 7C 40 00 40 06 [D3 74] C0 A8 B2 14 C6 FC CE 19
现在可以发送标头了。
然后,IPv4数据包的接收者以相同的方式创建接收到的标头的校验和:
bc <<< 'obase=16;ibase=16;4500 + 0034 + 5F7C + 4000 + 4006 + D374 + C0A8 + B214 + C6FC + CE19'
bc <<< 'obase=16;ibase=16;FFFB + 4'
有关更多信息,请参见Wikipedia entry。
¹将十六进制数反转意味着将其转换为二进制,翻转位,然后再次将其转换为十六进制。您可以使用online或使用Bash:hex_nr=0x2C8B; hex_len=$(( ${#hex_nr} - 2 )); inverted=$(printf '%X' "$(( ~ hex_nr ))"); trunc_inverted=${inverted: -hex_len}; echo $trunc_inverted