IP首部校验和算法

IP数据报首部校验和(长度是16位),用于检验首部的有效性和完整性。IP首部

校验和采用的是反码求和算法。就是把首部看成16位的整数序列。然后反码

求和。把得到的值放入首部校验和位置。反码求和算法如下:

0和0相加是0但要产生一个进位1,0和1相加是1,1和1相加是0.若最高位相加后产生进位,

则最后得到的结果要加1。

(0)反 + (0)反 = 1 + 1 = 10
(1)反 +(0)反 = 0 + 1 = 1
(1)反 + (1)反 = 0 + 0 = 0
在发送时,第一次发送前,首部校验和置0。然后用该算法算出校验和填充。接受端收到数
据后,用校验和算法(包含填充的检验和值)检验所有数据。结果应该为0。
#include "stdafx.h"
//16位反码求和算法
unsigned short checksum(unsigned short *buffer, int size)
{
unsigned long cksum = 0;
while(size>1)
{
cksum += *buffer++;
size -= sizeof(unsigned short);
}
if (size)
{
cksum += *(unsigned short*)buffer;
}
cksum = (cksum>>16) + (cksum&0xffff);
cksum += (cksum>>16);
return (unsigned short)(~cksum); //返回16位值
}
// 模拟数据
struct datasum
{
char data[50];//数据
unsigned short checksum;//校验和
       };
//测试程序
int _tmain(int argc, _TCHAR* argv[])
{
struct datasum msg = {"Hello World!",0};
msg.checksum=checksum((unsigned short*)&msg,sizeof(msg));
printf("checksum prev is: %d",msg.checksum);
msg.checksum=checksum((unsigned short*)&msg,sizeof(msg));
printf("checksum after is: %d",msg.checksum);
getchar();
return 0;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
IP数据报的校验和算法是一种很重要的数据完整性校验手段,该算法IP数据的发送和接收过程中都得到广泛应用。 该算法的实现步骤如下: 1. 首先将整个IP数据首部按照16bit一组进行分组,不足16bit且不是末尾则在末尾添加0 2. 将这些16bit的数字从第一个到最后一个相加,得到一个数值 3. 以32位为单位将这个数值进行反码运算,得到的结果即为校验和 参考样例代码: #include <stdio.h> #include <stdlib.h> #include <string.h> #define BUFFERSIZE 32 /* * 计算IP数据首部校验和 * @param buf 待计算数据首部 "struct ipheader" 的指针 * @param len 数据首部长度 (单位:bytes) * return 计算得到的校验和 */ unsigned short checksum(unsigned short *buf, int len){ unsigned long sum = 0; while(len > 1){ sum += *buf++; len -= 2; } if(len){ sum += *(unsigned char*)buf; } sum = (sum >> 16) + (sum & 0xffff); sum += (sum >> 16); return (unsigned short)(~sum); } struct ipheader{ unsigned char ver_ihl; /* 版本 (4 bits) + 首部长度 (4 bits) */ unsigned char tos; /* 服务类型(Type of Service) */ unsigned short total_len; /* 总长(Total Length) */ unsigned short ident; /* 标识(Identification) */ unsigned short frag_and_flags; /* 标志位(Flags) (3 bits) + 片偏移(Fragment offset) (13 bits) */ unsigned char ttl; /* 存活时间(Time to live) */ unsigned char protocol; /* 协议(Protocol) */ unsigned short checksum; /* 首部校验和(Header checksum) */ unsigned int sourceIP; /* 源IP地址(Source IP address) */ unsigned int destIP; /* 目的IP地址(Destination IP address) */ }; int main(){ unsigned char buffer[BUFFERSIZE]; memset(buffer,0,BUFFERSIZE); struct ipheader *ip = (struct ipheader*) buffer; ip->ver_ihl = 0x45; ip->tos = 0; ip->total_len = htons(sizeof(struct ipheader)); ip->ident = htons(54321); ip->frag_and_flags = 0; ip->ttl = 128; ip->protocol = 6; ip->checksum = 0; ip->sourceIP = inet_addr("192.168.1.101"); ip->destIP = inet_addr("192.168.1.1"); unsigned short check_sum = checksum((unsigned short*)ip,sizeof(struct ipheader)); printf("check sum=%d\n",check_sum); ip->checksum = check_sum; return 0; } 该程序首先定义了一个结构体ipheader,该结构体含了一个完整的IP首部,然后通过调用checksum函数计算该IP数据首部校验和。最后将计算得到的校验和存入IP首部中的checksum字段。运行该程序后即可得到IP数据首部校验和

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值