思路及代码
程序设计思路
-
main函数程序:以I/O流形式对文件进行读入数据(包括规则集、数据集、各类函数文件等),调用各分类函数,将结果写入目标文件
-
函数1:IP地址十进制表示转换成点分十进制
-
函数2:检测IP地址是否匹配,并以0/1作为返回值表示
-
函数3:检测端口是否匹配,并以规0/1作为返回值表示
-
函数4:检测传输协议是否匹配,并以0/1作为返回值表示
-
整体程序设计思路:
- 依次读入数据包
- 调用函数1将IP地址转换成规则集的表达形式
- 遍历规则集依次匹配对应规则,并用变量cnt计数
- 分别以规则集数组、IP地址、端口、传输协议等为参数传入,调用函数2/3/4
- 对其返回值进行判断,若都为1则输出cnt的值,否则读入下一条规则继续判断
所有子函数(具体代码请参照最下面的完整代码)
int ip_chansform(void);//转换规则IP,返回前缀长度
int ip_check(char a[]); //函数1:检测IP地址是否匹配,并以0/1作为返回值表示否/是,返回-1表示没有数据读入,即所有规则匹配结束
int port_check(int p); //函数2:检测端口是否匹配,并以0/1作为返回值表示否/是,返回-1表示没有数据读入,即所有规则匹配结束
int tcp_check(int t); //函数3:检测传输协议是否匹配,并以0/1作为返回值表示否/是,返回-1表示没有数据读入,即所有规则匹配结束
int stot(char *p,float length);//十六进制转换十进制
关键代码
- 读取规则IP并将其转换为十进制
int ip_chansform(void){//只读一条规则 //转换规则IP,返回前缀长度
int a[6],step,i=0,j;
char x,s[10];
// getc(p);
// if(feof(p)) return -1;
while(cin>>a[i]>>x){
// cout<<"\n"<<"a["<<i<<"]="<<a[i]<<" x="<<x<<endl;
ltoa(a[i],s,2);
if(strlen(s)<8){
for(j=0;j<8-strlen(s);j++){
ip_rule+=ex;
}
}
// cout<<s<<endl;
ip_rule+=s;
if(i>=3) break;
i++;
}
if(i<3) return -1;
cin>>step;
return step;
}
伪代码
#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
int main(){
clock_t start,finish;
start=clock();
fpos_t pos_1=0,pos_2=0;
FILE *p=freopen("input.txt","r",stdin);
freopen("out.txt","w",stdout);
char cip_1[35],cip_2[35],waste;//cip_1[]和cip_2[]用于存储转换后的IP地址
ll ip_1,ip_2,ans,i,j,port_1,port_2,tcp,k=0;
int check_1,check_2,check_3,check_4,check_5;
while(cin>>ip_1,cin>>ip_2,cin>>port_1,cin>>port_2,cin>>tcp){
// cout<<ip_1<<" "<<ip_2<<" "<<port_1<<" "<<port_2<<" "<<tcp<<endl;
int f=0,cnt=0,l1,l2;// f标记是否遍历规则集仍无法匹配而直接进入下一条数据的匹配;
将数据IP转换成二进制;
fgetpos(p,&pos_1);
cin.clear();
FILE *p2=freopen("rule1.txt","r",stdin);
// rewind(p);
while(cin>>waste){
匹配原目IP;
匹配目的IP;
匹配源目端口;
匹配目的端口;
匹配协议;
// cout<<check_1<<" "<<check_2<<endl;
if(check_1&&check_2&&check_3&&check_4&&check_5) break;
else if(check_1==-1||check_2==-1){
f=1;
break;
}
else{
cnt++;
}
}
if(f) cout<<"-1"<<endl;
else if(cnt==918) cout<<"-1"<<endl;
else cout<<cnt<<endl;
/* if(cin.rdstate()!=ios_base::eofbit){
cout<<"end"<<endl;
return 0;
}*/
cin.clear();
freopen("input.txt","r",stdin);
fsetpos(p,&pos_1);
// k++;·
}
// if(k==3) return 0;
finish=clock();
cout<<"程序执行时间为:"<<(double)(finish-start)/CLOCKS_PER_SEC<<endl;
return 0;
}
完整代码
#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
char ex='0'; //用于补全不够位数的二进制数
string ip_rule="";//用于存储转换二进制后的规则IP网络前缀
int ip_chansform(void);//转换规则IP,返回前缀长度
// void chansform(int c,char *a); //函数1:IP地址十进制表示转换成点分十进制表示(参数1:IP十进制 , 参数2:存储转换后的点分十进制IP地址的字符数组地址)
int ip_check(char a[]); //函数2:检测IP地址是否匹配,并以0/1作为返回值表示否/是,返回-1表示没有数据读入,即所有规则匹配结束
int port_check(int p); //函数3:检测端口是否匹配,并以0/1作为返回值表示否/是,返回-1表示没有数据读入,即所有规则匹配结束
int tcp_check(int t); //函数4:检测传输协议是否匹配,并以0/1作为返回值表示否/是,返回-1表示没有数据读入,即所有规则匹配结束
int judge(int a, int b, int c, int d, int e); //遍历规则集,以五元组作为参数传入,调用函数2/3/4并判断其返回是否都为1,
//若是,则返回规则编号;若否,则返回-2,继续循环读入下一条rule,再次调用函数2/3/4继续判断;
//check_1的值为-1,表示此时编号已经为规则集内最大,则返回-1
int stot(char *p,float length);//十六进制转换十进制
int main(){
/* ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
cout.flush();*/
clock_t start,finish;
start=clock();
fpos_t pos_1=0,pos_2=0;
FILE *p=freopen("input.txt","r",stdin);
freopen("out.txt","w",stdout);
char cip_1[35],cip_2[35],waste;//cip_1[]和cip_2[]用于存储转换后的IP地址
ll ip_1,ip_2,ans,i,j,port_1,port_2,tcp,k=0;
int check_1,check_2,check_3,check_4,check_5;
while(cin>>ip_1,cin>>ip_2,cin>>port_1,cin>>port_2,cin>>tcp){
// cout<<ip_1<<" "<<ip_2<<" "<<port_1<<" "<<port_2<<" "<<tcp<<endl;
int f=0,cnt=0,l1,l2;// f标记是否遍历规则集仍无法匹配而直接进入下一条数据的匹配;
ltoa(ip_1,cip_1,2);
ltoa(ip_2,cip_2,2);
l1=strlen(cip_1);
l2=strlen(cip_2);
if(strlen(cip_1)<32){
for(j=l1-1;j>=0;j--){
cip_1[j+32-l1]=cip_1[j];
}
for(j=0;j<=31-l1;j++){
cip_1[j]='0';
}
cip_1[32]='\0';
}
if(strlen(cip_2)<32){
for(j=l2-1;j>=0;j--){
cip_2[j+32-l2]=cip_2[j];
}
for(j=0;j<=31-l2;j++){
cip_2[j]='0';
}
cip_2[32]='\0';
}
// cout<<cip_1<<" "<<cip_2<<endl;
fgetpos(p,&pos_1);
cin.clear();
FILE *p2=freopen("rule1.txt","r",stdin);
// rewind(p);
while(cin>>waste){
check_1=ip_check(cip_1);
check_2=ip_check(cip_2);
check_3=port_check(port_1);
check_4=port_check(port_2);
check_5=tcp_check(tcp);
// cout<<check_1<<" "<<check_2<<endl;
if(check_1&&check_2&&check_3&&check_4&&check_5) break;
else if(check_1==-1||check_2==-1){
f=1;
break;
}
else{
cnt++;
}
}
if(f) cout<<"-1"<<endl;
else if(cnt==918) cout<<"-1"<<endl;
else cout<<cnt<<endl;
/* if(cin.rdstate()!=ios_base::eofbit){
cout<<"end"<<endl;
return 0;
}*/
cin.clear();
freopen("input.txt","r",stdin);
fsetpos(p,&pos_1);
// k++;·
}
// if(k==3) return 0;
finish=clock();
cout<<"程序执行时间为:"<<(double)(finish-start)/CLOCKS_PER_SEC<<endl;
return 0;
}
int ip_chansform(void){//只读一条规则 //转换规则IP,返回前缀长度
int a[6],step,i=0,j;
char x,s[10];
// getc(p);
// if(feof(p)) return -1;
while(cin>>a[i]>>x){
// cout<<"\n"<<"a["<<i<<"]="<<a[i]<<" x="<<x<<endl;
ltoa(a[i],s,2);
if(strlen(s)<8){
for(j=0;j<8-strlen(s);j++){
ip_rule+=ex;
}
}
// cout<<s<<endl;
ip_rule+=s;
if(i>=3) break;
i++;
}
if(i<3) return -1;
cin>>step;
return step;
}
int ip_check(char a[]){ //函数1:检测IP地址是否匹配,并以0/1作为返回值表示否/是,返回-1表示没有数据读入,即所有规则匹配结束
ip_rule="";
int t=ip_chansform(),i=0;
// cout<<t<<endl;
// cout<<ip_rule<<" ";
if(t==-1) return -1;
for(i=0;i<t;i++){
if(a[i]!=ip_rule[i]) break;
}
if(i==t) return 1;
else return 0;
}
int port_check(int p){ //函数2:检测端口是否匹配,并以0/1作为返回值表示否/是,返回-1表示没有数据读入,即所有规则匹配结束
int l,r;
char x;
cin>>l>>x>>r;
// cout<<"l="<<l<<"r="<<r<<endl;
if(p>=l&&p<=r) return 1;
else return 0;
}
int tcp_check(int t){ //函数3:检测传输协议是否匹配,并以0/1作为返回值表示否/是,返回-1表示没有数据读入,即所有规则匹配结束
char l[5],r[5],x,y;
int i,b=0,e=0;
cin>>x>>y>>l[0]>>l[1];
// cout<<l[0]<<l[1]<<endl;
cin>>x;
cin>>x>>y>>r[0]>>r[1];
// cout<<r[0]<<r[1]<<endl;
if(r[0]=='0'&&r[1]=='0') return 1;
b=stot(l,2);
// e=stot(r,2);
if(t==b) return 1;
else return 0;
}
int stot(char *p,float length){
int sum=0,i,t=length;
for(i=0;i<t;i++){
if(p[i]>='0'&&p[i]<='9'){
sum+=(p[i]-'0')*pow(16,--length);
}else if(p[i]>='A'&&p[i]<='F'){
sum+=(p[i]-'A'+10)*pow(16,--length);
}
}
// cout<<sum<<endl;
return sum;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?