论文部分内容阅读
[摘要]探讨IPV4首部检验和校验和算法分析,并给出实现代码。
[关键词]IPV4 首部检验和 访问控制 数字签名
中图分类号:TP3文献标识码:B 文章编号:1671-7597 (2008) 0220058-01
一、校验和概述
所谓校验和是把8位字节视为整数,然后把该8位字节构成的序列求和所计算出的小的整数值。校验和用于检测当8位字节序列从一台计算机向另一台计算机传送时所产生的差错。一般校验和由协议软件计算,当传送时把它附加在分组中。接收时协议软件重新计算校验和,并与发送的校验和进行比较,从而达到核对分组内容的目的。许多TCP/IP协议采用反码运算计算16位校验和,分组中所有整数字段均按网络字节次序存储。
首部校验和用于确保头部数值的完整性。IP校验和把头部视为按网络字节次序的16位整数序列,采用反码运算把它们累加起来,然后再取结果的反码。为达到计算校验和的目的,假定头部校验和字段内容为0。
指出下面一点是重要的,即校验和只适用于IP头部,而不适用于数据。把头部校验和和数据校验和分开,有优点也有缺点。因为和数据相比头部通常只占较少8位字节,把校验和分开,路由器只需计算头部校验和,从而缩短了路由器处理时间。把校验和分开也使高层协议可以选择自己的数据校验和模式。主要的缺点头部校验和可用来检测路由器内存坏字引起的差错。采用反码运算比标准加法更健壮。应该指出,头部校验和每次跳跃(在每个路由器)必须重新计算,因为至少有一个字段总是改变(生命期字段),不过可以采用IPv4有头部校验和,但IPv6是否要校验和有争议。反对校验和的人说,任何应用程序如果确实关心数据的完整性,无论如何也要有传输层校验和,除了数据链路层校验和之外,在IP层再加另外一个校验和太过分了。而且经验指出,IP校验和计算是IPv4的主要开销。最后反校验和阵营取得了胜利,IPv6 不再有校验和。
二、校验和算法
(一)校验和生成器
在发送方,校验和生成器将数据单元细分成大小都为N(通常是16)比特的分段。这些分段采用反码算法加在一起,使得整个结果仍然是N比特长。该校验和随后取反,并当作冗余位加在原始数据单元的末尾,称作校验和字段。发送方遵循以下步骤:数据单元被分成K段,每段N比特;将所有段按反码方式相加求和;对最后结果取反得到校验和;将校验和与数据一起发送。接收方遵循以下步骤:数据单元被分成K段,每段N比特将所有段按反码方式相加求和;取反。若结果为0,则接收数据;否则丢弃。
(二)校验和校验器
接收方切分数据单元,将所有分段相加并对结果取反。如果扩展的数据单元是完整正确的,那么各数据段和校验和字段相加的最后结果应该是0。如果结果不是0,就意味着数据包包含着差错,因而接收方丢弃该数据单元。
三、校验和算法的分析
校验和检测所有涉及奇数个比特的差错,以及大多数涉及偶数个比特的差错。如果在某一分段中的一个或多个比特被破坏,并且在下一个分段中具有相反值的对应位也被破坏,这些列的将不变,因此接收方将检测不出差错。如果一个分段的最后一个数位是0并且在传输中变成了1,那么另一个分段的最后一个1变成了0将造成该差错的不可检测。校验和保留了所有的进位,尽管两个0变成了1不会改变它们自身列的值,却会改变高位列的数值。当一个比特的反相被另一个数据分段对应数位上具有相反值的比特反相所抵消时,该差错对于校验和来说是不可检测的。
四、校验和算法的实现
typedef struct IPHead//报头结构
{BYTE ip_type;BYTE ip_verlen; WORD ip_totallength; WORD ip_id;
WORD ip_offset; BYTE ip_protocol; BYTE ip_time;
WORD ip_checksum; DWORD ip_srcaddr; DWORD ip_destaddr; }
*IPhPot;
class IP
{public: //计算首部检验和
static WORD checksum(IPHead *ip,int hsize)
{if (ip == NULL)
{::MessageBox(NULL,"how are you","空指针",MB_OK); }
ip->ip_checksum = 0x0000;
DWORD checkSum = 0x00000000; //存放二进制求和结果
WORD hight = 0x0000; //存放二进制求和结果的高16位
WORD low = 0x0000; //存放二进制求和结果的低16位
WORD *p = (WORD *)ip;
while(hsize>0)//各位求和
{ checkSum += *p++; //将指向对象的指针转化成指向无符号短整数指针
hsize -= sizeof(WORD); }
low = (WORD)checkSum;
hight = (WORD)(checkSum >>= 16);
return ~(low + hight); //返回求和结果的取反值 }
//判断给定的ip数据报是否正确
static BOOL isRight(IPHead *ip)
{if (ip == NULL)
{::MessageBox(NULL,"how are you","空指针",MB_OK); }
int hsize = sizeof(*ip);
WORD sum = 0x0000; //ip首部效验和
DWORD checkSum = 0x00000000; //存放二进制求和结果
WORD hight = 0x0000; //存放二进制求和结果的高16位
WORD low = 0x0000; //存放二进制求和结果的低16位
WORD *p = (WORD *)ip;
while(hsize>0)//各位求和
{checkSum += *p++;//将指向对象的指针转化成指向无符号短整数指针
hsize -= sizeof(WORD); }
low = (WORD)checkSum;
hight = (WORD)(checkSum >>= 16);
sum = ~(low + hight); //返回求和结果的取反值
if (sum == 0) {return TRUE; }
Else {return FALSE; }}};
最终实现了IPV4首部检验和校验和算法代码。
参考文献:
[1]Tanenbaum A S.Computer Networks[M].3rd ed,北京:清华大学出版社,1997.
[2]李毅、张帆等,IPv4头部校验和的反码算法,武汉理工大学学报2003,4.
[关键词]IPV4 首部检验和 访问控制 数字签名
中图分类号:TP3文献标识码:B 文章编号:1671-7597 (2008) 0220058-01
一、校验和概述
所谓校验和是把8位字节视为整数,然后把该8位字节构成的序列求和所计算出的小的整数值。校验和用于检测当8位字节序列从一台计算机向另一台计算机传送时所产生的差错。一般校验和由协议软件计算,当传送时把它附加在分组中。接收时协议软件重新计算校验和,并与发送的校验和进行比较,从而达到核对分组内容的目的。许多TCP/IP协议采用反码运算计算16位校验和,分组中所有整数字段均按网络字节次序存储。
首部校验和用于确保头部数值的完整性。IP校验和把头部视为按网络字节次序的16位整数序列,采用反码运算把它们累加起来,然后再取结果的反码。为达到计算校验和的目的,假定头部校验和字段内容为0。
指出下面一点是重要的,即校验和只适用于IP头部,而不适用于数据。把头部校验和和数据校验和分开,有优点也有缺点。因为和数据相比头部通常只占较少8位字节,把校验和分开,路由器只需计算头部校验和,从而缩短了路由器处理时间。把校验和分开也使高层协议可以选择自己的数据校验和模式。主要的缺点头部校验和可用来检测路由器内存坏字引起的差错。采用反码运算比标准加法更健壮。应该指出,头部校验和每次跳跃(在每个路由器)必须重新计算,因为至少有一个字段总是改变(生命期字段),不过可以采用IPv4有头部校验和,但IPv6是否要校验和有争议。反对校验和的人说,任何应用程序如果确实关心数据的完整性,无论如何也要有传输层校验和,除了数据链路层校验和之外,在IP层再加另外一个校验和太过分了。而且经验指出,IP校验和计算是IPv4的主要开销。最后反校验和阵营取得了胜利,IPv6 不再有校验和。
二、校验和算法
(一)校验和生成器
在发送方,校验和生成器将数据单元细分成大小都为N(通常是16)比特的分段。这些分段采用反码算法加在一起,使得整个结果仍然是N比特长。该校验和随后取反,并当作冗余位加在原始数据单元的末尾,称作校验和字段。发送方遵循以下步骤:数据单元被分成K段,每段N比特;将所有段按反码方式相加求和;对最后结果取反得到校验和;将校验和与数据一起发送。接收方遵循以下步骤:数据单元被分成K段,每段N比特将所有段按反码方式相加求和;取反。若结果为0,则接收数据;否则丢弃。
(二)校验和校验器
接收方切分数据单元,将所有分段相加并对结果取反。如果扩展的数据单元是完整正确的,那么各数据段和校验和字段相加的最后结果应该是0。如果结果不是0,就意味着数据包包含着差错,因而接收方丢弃该数据单元。
三、校验和算法的分析
校验和检测所有涉及奇数个比特的差错,以及大多数涉及偶数个比特的差错。如果在某一分段中的一个或多个比特被破坏,并且在下一个分段中具有相反值的对应位也被破坏,这些列的将不变,因此接收方将检测不出差错。如果一个分段的最后一个数位是0并且在传输中变成了1,那么另一个分段的最后一个1变成了0将造成该差错的不可检测。校验和保留了所有的进位,尽管两个0变成了1不会改变它们自身列的值,却会改变高位列的数值。当一个比特的反相被另一个数据分段对应数位上具有相反值的比特反相所抵消时,该差错对于校验和来说是不可检测的。
四、校验和算法的实现
typedef struct IPHead//报头结构
{BYTE ip_type;BYTE ip_verlen; WORD ip_totallength; WORD ip_id;
WORD ip_offset; BYTE ip_protocol; BYTE ip_time;
WORD ip_checksum; DWORD ip_srcaddr; DWORD ip_destaddr; }
*IPhPot;
class IP
{public: //计算首部检验和
static WORD checksum(IPHead *ip,int hsize)
{if (ip == NULL)
{::MessageBox(NULL,"how are you","空指针",MB_OK); }
ip->ip_checksum = 0x0000;
DWORD checkSum = 0x00000000; //存放二进制求和结果
WORD hight = 0x0000; //存放二进制求和结果的高16位
WORD low = 0x0000; //存放二进制求和结果的低16位
WORD *p = (WORD *)ip;
while(hsize>0)//各位求和
{ checkSum += *p++; //将指向对象的指针转化成指向无符号短整数指针
hsize -= sizeof(WORD); }
low = (WORD)checkSum;
hight = (WORD)(checkSum >>= 16);
return ~(low + hight); //返回求和结果的取反值 }
//判断给定的ip数据报是否正确
static BOOL isRight(IPHead *ip)
{if (ip == NULL)
{::MessageBox(NULL,"how are you","空指针",MB_OK); }
int hsize = sizeof(*ip);
WORD sum = 0x0000; //ip首部效验和
DWORD checkSum = 0x00000000; //存放二进制求和结果
WORD hight = 0x0000; //存放二进制求和结果的高16位
WORD low = 0x0000; //存放二进制求和结果的低16位
WORD *p = (WORD *)ip;
while(hsize>0)//各位求和
{checkSum += *p++;//将指向对象的指针转化成指向无符号短整数指针
hsize -= sizeof(WORD); }
low = (WORD)checkSum;
hight = (WORD)(checkSum >>= 16);
sum = ~(low + hight); //返回求和结果的取反值
if (sum == 0) {return TRUE; }
Else {return FALSE; }}};
最终实现了IPV4首部检验和校验和算法代码。
参考文献:
[1]Tanenbaum A S.Computer Networks[M].3rd ed,北京:清华大学出版社,1997.
[2]李毅、张帆等,IPv4头部校验和的反码算法,武汉理工大学学报2003,4.