网际检验和算法,以接收方计算IP首部检验和为例
#include<iostream>
#include <fstream>
#include<string>
#include<cstring>
#include <algorithm>
using namespace std;//非遂爻辞
string h="0123456789abcdef";//16进制
string HexAdd(string pri,string now){//实现字符串的16进制循环加法
int cf=0;//进位标识符
for(int i=3;i>=0;--i){//从低位开始
int ph,nh;//设置pri和now第i位分别对应于h的标号,可以通过标号之和取模16作为标号,从h里找到对应符号,实现加法
for(int j=0;j<16;++j){//pri开找
if(pri[i]==h[j]){ph=j;break;}
}
for(int j=0;j<h.length();++j){//now开找
if(now[i]==h[j]){nh=j;break;}
}
int pnch=ph+nh+cf;//标号求和
cf=0;//重置cf
if(pnch>=16)cf=1;//若产生进位,cf置1
pri[i]=h[pnch%16];//取模获得对应符号
}
if(cf!=0)pri=HexAdd(pri,"0001");//最高位有进位,通过递归保证循环加法
return pri;//返回结果
}
int main(){
string fname;//打开的文件名
//路径有:
//.\\testfile\\icmp.txt
//.\\testfile\\udp.txt
//.\\testfile\\tcp.txt
string temp;//获取文件内容于temp字符串
cout<<"请输入想要打开的文件:"<<endl;//静态提示路径
cout<<".\\testfile\\icmp.txt"<<endl;
cout<<".\\testfile\\udp.txt"<<endl;
cout<<".\\testfile\\tcp.txt"<<endl;
cin>>fname;
fstream fs(fname);//打开文件
if(fs.is_open()){//判断是否成功打开
fs>>temp;
cout<<"原始内容为:"<<temp<<endl;//输出原始内容
//接下来进行网际校验,因为都是ip数据报,本算法仅计算ip首部校验,至于icmp、udp、tcp的算法相同,取的数据部分不同罢了,下面是算法步骤:
//取ip首部,每两个字节为一组,每组循环加法,和取反
//需要注意的是,发送方的校验位先置为0x0000,算出后再赋值;接收方不用,直接算,若最终结果为0x0000,则接收,否则丢弃
//这算法具体实现,结合实际,就当咱是接收方好了
string pri="0000";//记录累加信息,初始为零
for(int i=28;i<68;i+=4){//测试文件是通过wireshark导出后加工而成的数据,其前14个字节记录着源mac、目的mac和ip协议版本,并不是ip首部,所以跳过
string now=temp.substr(i,4);//每两个字节为单位
pri=HexAdd(pri,now);//开加
cout<<"pri "<<i<<" = "<<pri<<endl;//输出每次加后的结果,做到流程清晰
}
for(int i=3;i>=0;--i){//结果取反
int cpn;//pri每位反值的序号
for(int j=0;j<h.length();++j)if(pri[i]==h[j]){cpn=h.length()-1-j;break;}//找到反值序号
pri[i]=h[cpn];//将pri每位取反
}
cout<<"接收方的ip首部检验和结果为:0x"<<pri<<endl;
fs.close();//关闭文件流
}else cout<<"文件打开失败!";cout<<endl;
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律