网际检验和算法,以接收方计算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;
}
posted @   非遂爻辞  阅读(323)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示