C#中实现累加校验和计算和校验

为建立中文知识库加块砖       ——中科大胡不归

0. 前言

如果必须加入一种方法来校验协议数据,累加校验不失为一种好的方案。MD5计算出的Hash太长了,校验和不过1或2个字节,当然MD5的安全性也不是校验和能比的。

1. 校验和原理

1.1 发送方生成检验和

1.将发送的进行检验和运算的数据分成若干个16位的位串,每个位串看成一个二进制数,这里并不管字符串代表什么,是整数、浮点数还是位图都无所谓。

2.将IP、UDP或TCP的PDU首部中的检验和字段置为0,该字段也参与检验和运算。

3.对这些16位的二进制数进行1的补码和(one's complement sum)运算,累加的结果再取反码即生成了检验码。将检验码放入检验和字段中。

其中1的补码和运算,即带循环进位(end round carry)的加法,最高位有进位应循环进到最低位。反码即二进制各位取反,如0111的反码为1000。

1.2 接收方校验检验和

1.接收方将接收的数据(包括检验和字段)按发送方的同样的方法进行1的补码 和运算,累加的结果再取反码。

2.校验,如果上步的结果为0,表示传输正确;否则,说明传输有差错。

1.3 算法图示

2. 代码实现

2.1 生成检验和

public static byte[] GetCheckSum(byte[] data)
        {
            List m = new List();
            int sum = 0;
            for (int i = 0; i < data.Length; i++)
            {
                m.Add(data[i]);
                sum += data[i];
            }

            sum = sum % 256;
            sum = ~sum + 1;
            
            m.Add((byte) sum);

            return m.ToArray();
        }

返回值是追加了校验和的原始字节数组。

2.2 接收方校验

public static byte DoSumCheck(byte[] data)
        {
            byte cs = 0;
            for (int i = 0; i < data.Length; i++)
            {
                cs = (byte)((cs + data[i]) % 256);
            }
            return cs;
        }

DoSumCheck的参数就是原字节数组在尾部加上了校验和,如果数据正确运算结果就为00。

3. 效果展示

调用演示:



运行结果:


参考文章:

  1. 校验和

你可能感兴趣的:(C#中实现累加校验和计算和校验)