Checksum 校验和
CheckSum(校验和):网络传输报文头部有效性检验的一种方式,其基本思想是,对头部进行校验和运算,再对头部取和,所有位应当全为“1”,其程序实现如下:
WORD CheckSum(const WORD *addr, WORD len)
{
DWORD dwSum = 0;
WORD wOddByte = 0;
WORD wAnswer = 0;
dwSum = 0;
while(len>1)
{
dwSum += *addr++;
len -= 2;
}
if( 1==len )
{
wOddByte = 0;
*((unsigned char*)&wOddByte) = *(unsigned char*)addr;
dwSum +=wOddByte;
}
dwSum = (dwSum>>16) + (dwSum&0xfff);
dwSum += (dwSum>>16);
wAnswer = (unsigned int)~dwSum;
return wAnswer;
}
从程序实现可以看出wAnswer 最后等于dwSum的反码,
我们做以下假设:
填放校验和的字段为CSC,除校验和以外的字段按双字节加起来和为B,B的反码C,则调用CheckSum函数以后,有以下关系:
B = 报文头按双字节加起来的和
C = ~B
CSC = C
我们知道,B + ~B = 216 – 1 D (为WORD型)
=1111111111111111 B
同理
B + C = 216 – 1 D (为WORD型)
=1111111111111111 B
由于B是报文头的各个字段的值的和,正确传输时这些值并不改变,同时我们把CSC置为C,即~B,所以当我们收到报文以后,只需做如下操作:
D = CSC + B
看D是否为(216 – 1)即可。也可理解为判断D的每一位是否为“1”
(216 – 1 = 1111111111111111 B)
CheckSum(校验和):网络传输报文头部有效性检验的一种方式,其基本思想是,对头部进行校验和运算,再对头部取和,所有位应当全为“1”,其程序实现如下:
WORD CheckSum(const WORD *addr, WORD len)
{
DWORD dwSum = 0;
WORD wOddByte = 0;
WORD wAnswer = 0;
dwSum = 0;
while(len>1)
{
dwSum += *addr++;
len -= 2;
}
if( 1==len )
{
wOddByte = 0;
*((unsigned char*)&wOddByte) = *(unsigned char*)addr;
dwSum +=wOddByte;
}
dwSum = (dwSum>>16) + (dwSum&0xfff);
dwSum += (dwSum>>16);
wAnswer = (unsigned int)~dwSum;
return wAnswer;
}
从程序实现可以看出wAnswer 最后等于dwSum的反码,
我们做以下假设:
填放校验和的字段为CSC,除校验和以外的字段按双字节加起来和为B,B的反码C,则调用CheckSum函数以后,有以下关系:
B = 报文头按双字节加起来的和
C = ~B
CSC = C
我们知道,B + ~B = 216 – 1 D (为WORD型)
=1111111111111111 B
同理
B + C = 216 – 1 D (为WORD型)
=1111111111111111 B
由于B是报文头的各个字段的值的和,正确传输时这些值并不改变,同时我们把CSC置为C,即~B,所以当我们收到报文以后,只需做如下操作:
D = CSC + B
看D是否为(216 – 1)即可。也可理解为判断D的每一位是否为“1”
(216 – 1 = 1111111111111111 B)