周四要给工作室的小朋友们继续培训计算机网络,要讲的内容是传输层,于是今天就在准备相应的材料,重新看回谢希仁老师的课本过程中又加深了一点理解,然后看到了当时碰到的第一个难点,UDP协议的校验和的计算。
其实本质上来说这个计算原理还是不难的,就是一个二进制反码求和运算,具体来说就是。
$$ 0 + 0 = 0 $$
$$ 1 + 0 = 0 + 1 = 1 $$
$$ 1 + 1 = 10 $$
$$其中10中的1加到了下一列去,如果是最高列的1+1,那么得到的10留下0,1移到最低列,与最低位再做一次二进制加法即可。$$
在谢老师的这本书里,讲到的是一个15字节的UDP数据在发送方怎么进行数据的检验,然后列出了一个二进制的竖式并给出一个结果,然而并没有讲述是怎么计算出来的。经过我不断的努力,终于把二进制计算的过程整个写出来了。之前在数计院上课的时候,老师讲过一个较为之简单的十六进制计算法,对比之下确实是简单很多。好了,先上图。
谢老师在课本里面给出的题目是这样子的
|
|
在二进制版中,是不可以直接从右边第一列开始做竖式相加的,不要说十进制的竖式相加,二进制的竖式相加都做不到。
正确的做法是:
(1) 让第一行和第二行做二进制反码运算。
根据上述的规则,当碰到1+1=10时,在左邻侧一列下面写个小1(类似以前做十进制进位加法),然后侧列进行二进制反码运算得出一个数,如果没有进位,就继续与刚才的进位做二进制反码运算,如果有进位,则先把进位的小1写在相邻高侧列的下方,取个位来与其相加。有进位的只有1+1=10的情况,0不论加什么进位都不会有进位,而如果第一次计算没有进位时,只有产生1的情况下才会有进位,总而言之,对于每一列,都只会有至多一次的进位,所以不用担心进位会跨列的问题。这样子做要注意的就是不要写错数字了,比如我自己在写这张纸之前已经打过两次草稿了,然而还是会写错。
对于高位有1的情况,就是把1挪到最低位,再做一次二进制反码计算,本质来说就是取补码。
(2) 将第一行和第二行的结果与第三行做二进制反码计算,以此类推。
(3) 运算结果取反,得到校验和。
在十六进制版中,运算量会大大减小,主要的计算步骤如下:
(1) 从右边第一列开始,按照十进制来计算第一列的值。
在这里第一列算出来是107,写成8位二进制就是01101011。
(2) 根据算出来的结果分成两部分,左边的4位化成十进制,作为下一列进位时加的数,右边4位化成16进制,作为第一列的结果。
这里就是610B16,图片误算成D,6作为下一列运算时要加上的对象,B作为第一列的结果。
(3) 十进制计算第二列的结果,加上第一列得到的进位得到第二列的一个十进制数字,化为二进制,根据第二步来进行判断,依次类推。
在这里第二列算到的是24,加上6就是30,化为8位二进制就是00011110,也就是1E,第二列的结果为1,第三列的十进制进位为1。接着可以算到第三列的结果为6,十进制进位为4。
(4) 最高位算出最后的十进制结果后,化为二进制时,右边4位作为最终结果,左边4位移入下一列,用上一步得到的结果96EB,加上0010,得到最后结果,这里图片的最后一步写错了,不应该舍弃。
最后能得到结果为96ED。
(5) 结果取反,得到校验码。
校验码为6912。
好了这次先针对这个特定的问题提出了解决方案,有时间要好好整理下关于计算机的原码、反码和补码的知识。