⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ip.txt

📁 判断一个IP地址是否合法
💻 TXT
字号:
#include<iostream.h>
#include<string.h>
#include<stdlib.h>
#include<stdio.h>
#include<math.h>
#include<ctype.h>

//类结构
class ipTest{
	char ip[16];   //定义ip数组,存放ip地址
	char subnetPlusMask[19]; //定义subnetPlusMask数组,存放子网号和子网掩码中1的个数
	char subnet[19];   //定义subnet数组,存放子网号
	char TempIp[16];   //定义TempIp数组,存放临时的ip地址
	char TempSub[19];  //定义TempSub数组,存放临时的子网号
	int mask;   //定义整型mask,存放子网掩码中1的个数
	bool maskIsValid;//定义布尔值maskIsValid,存放判断mask真值的变量

public:
	ipTest(char *,char *); //定义ipTest函数
	~ipTest(){};
	bool NoIllegalChar(char *);  //非法字符的判断
	bool ipIsValid(char *);  //判断IP地址是否合法
	bool subnetIsValid(char *);  //判断子网号是否合法
	void belong();    //判断IP是否为子网成员
	print();//定义输出函数print
};

//主函数
void main(int argc,char *argv[]){
	if(argc != 3){  //判断参数格式是否正确
		cout<<"error"<<endl<<"format shoud be:ip_test subnet/mask ip"<<endl;//输出错误信息
		return;
	}
	else{
		if(strlen(argv[1]) > 18){  //先判断最简单的错误,子网号及子网掩码长度和是否超出
			cout<<"subnet/mask is too long";  //输出错误信息
			return;
		}
		if(strlen(argv[2]) > 15){ //ip地址长度是否超出
			cout<<"ip is too long";//输出错误信息
			return;
		}

		ipTest test(argv[1],argv[2]); //实例化ipTest类
		test.print();          //完成相应判别并输出结果
	}
}

//构造函数
ipTest::ipTest(char* subnetPlusMask,char *ip){
	maskIsValid = true;
	char temp[2];
//把'/'前的字符复制到subnet字符数组中
	int smLen = strlen(subnetPlusMask); // 定义smLen为subnetPlusMask的长度
	for(int i = 0;i < smLen && subnetPlusMask[i] != '/';i++){
		this->subnet[i] = subnetPlusMask[i];  //对subnet数组赋值,值为subnetPlusMask中的数值
		this->TempSub[i] = subnetPlusMask[i]; //对TempSub数组赋值,值为subnetPlusMask中的数值
	}
	subnet[i] = '\0';//给数组加上结束符
	TempSub[i] = '\0'; //给数组加上结束符
	if(i >= smLen-3&&i<=smLen-2){  //初始化mask和maskIsValid
		if(i == smLen-2){
			temp[0] = subnetPlusMask[i+1]; 
			if(!isdigit(temp[0])) //判断temp中的值是否为字符
				maskIsValid = false;
		}
		else if(i == smLen-3){
			temp[0] = subnetPlusMask[i+1];
			temp[1] = subnetPlusMask[i+2];
			if(!(isdigit(temp[0])&&isdigit(temp[1]))) //判断temp中的值是否为字符
				maskIsValid = false;
		}
		mask = atoi(temp); //将temp中的字符数值化
		if(mask<0 || mask >32) //判断mask值是否超出范围
			maskIsValid = false;
	}
	else //用十进制数表示的掩码中1的个数只能是一位数或者两位数
		maskIsValid = false;
	
	strcpy(this->subnetPlusMask,subnetPlusMask); //给subnetPlusMask赋值
	strcpy(this->ip,ip); //给IP赋值
	strcpy(this->TempIp,ip);
}

//调用判别函数,并输出结果
ipTest::print(){
	bool subIsV = subnetIsValid(TempSub);
	bool ipIsV = ipIsValid(TempIp);

	if(!subIsV)  //subnet非法
		cout<<"subnet is invalid!"<<endl;
	else
		cout<<"valid subnet:"<<subnet<<endl;

	if(!maskIsValid)  //mask非法
		cout<<"mask is invalid!"<<endl;
	else
		cout<<"valid mask:"<<mask<<endl;

	if(!ipIsV) //ip非法
		cout<<"ip is invalid!"<<endl;
	else
		cout<<"valid ip:"<<ip<<endl;

	//判断ip是否belong subnet
	if(subIsV && ipIsV && maskIsValid)
		belong();
}

//子网数,判断输入是否含有非数字字符
bool ipTest::NoIllegalChar(char *ch){
	unsigned int i,k=0;
	for(i=0;i<strlen(ch);i++){
		if(isdigit(*(ch+i))==0){  //判断每一位是否为数字字符
			return false;
		}
	}
	return true;   //若不含有非法数字字符则返回true
}

//判别IP地址是否合法
bool ipTest::ipIsValid(char * ip){
	char ch[]=".";   //分隔符
	char *token,*dot[4];
	int iplen = 0;
    int dotnum=0;
	char addr[18];
	int len=strlen(ip);
	strcpy(addr,ip);

	token = strtok(ip,ch); //以"."标志将IP字符串按节分开
	while(token!=NULL){   //循环进行,直到结束
		dot[iplen]=token; //将分开的每段赋值给dot
		iplen++;
		token = strtok(NULL,ch);
	}
    for(int i=0;i<len;i++) //计算地址中"."的个数
    {
        if(addr[i]=='.')
		{
			dotnum++;
		}
    }
    if(dotnum!=3)
	{
		cout<<"地址中分隔符应为3个!"<<endl;
		return false;
	}
    for(i=0;i<len-1;i++)
	{
		if(addr[i]=='.' && addr[i+1]=='.')
		{
			cout<<"地址中不能出现连续的分隔符!"<<endl;
			return false;  
		}
	} 
	if(addr[len-1]=='.')
	{
		cout<<"地址最后位不能为分隔符!"<<endl;
		return false;
	}

	if(iplen != 4)  //段数不对
		return false;
	for( i = 0; i < 4; i++){
		if(!NoIllegalChar(dot[i])||atoi(dot[i])>255) //有非法字符或某段值非法
			return false;
	}

	return true;
}

//判断子网号是否合法
bool ipTest::subnetIsValid(char* subnet){
	if(!ipIsValid(subnet))  //调用判别IP地址合法性的函数
		return false;
	return true;
}

//判断IP是否为子网成员,判断子网号与掩码是否匹配,以及子网号、主机号全0全1问题
void ipTest::belong(){
	int subLen = strlen(subnet); //定义子网号长度
	int ipLen = strlen(ip);//定义ip地址长度

	unsigned int iIPA,iSubA,iMask; //定义iIPA,iSubA,iMask
	unsigned char subA[4],ipA[4];  //定义subA,ipA
	char temp[3]; // 定义temp临时变量
	int i,j,t = 0;

	for (i = 0, j= 0;i<subLen;i++){  //不用再检错
		if(subnet[i] !='.')
			temp[j++]=subnet[i]; //temp数组中放'.'间的串
		else{
			subA[3-t] = atoi(temp);  //subA数组中放'.'间的数据
			j=0;
			t++;
			temp[0]=temp[1]=temp[2]='\0'; //temp中的数据清除
		}
	}
	subA[0]=atoi(temp); //subA数组中放'.'间的数据中最后一个数据
	temp[0]=temp[1]=temp[2]='\0';//temp中的数据清除
	iSubA=*(unsigned int *)subA; //iSubA中放subnet中'.'除外的串对应的数

	for(i=0,j=0,t=0;i<ipLen;i++){ //不用再检错  同上
		if(ip[i]!='.')
			temp[j++]=ip[i];
		else{
			ipA[3-t]=atoi(temp);
			j=0;
			t++;
			temp[0]=temp[1]=temp[2]='\0';
		}
	}
	ipA[0]=atoi(temp);
	iIPA=*(unsigned int*)ipA; //iIPA中放IP中'.'除外的串对应的数

	iMask = 0xffffffff;
	iMask<<=(32-mask);
	                       //获得掩码
	if((iSubA | iMask)!= iMask){ //说明sub与mask不匹配  位或操作
		cout<<"子网号与掩码不匹配,error!"<<endl;
		return;
	}
	if((iSubA^iMask)==0){ //说明子网号全1  位异或操作
		cout<<"子网号全1,error!"<<endl;
		return;
	}
	if((iSubA&iMask)==0){ //说明子网号全0  位与操作
		cout<<"子网号全0,error!"<<endl;
		return;
	}

	if((iSubA)==(iIPA&iMask)){ //IP和掩码与,结果和子网号比较
		if((iIPA|iMask)==iMask){  //说明主机号全0
			cout<<"主机号全0,error!"<<endl;
			return;
		}
		if((iIPA|iMask)==0xffffffff){ //说明主机号全1
			cout<<"主机号全1,error!"<<endl;
			return;
		}
		//ip属于subnet
		cout<<" "<<ip<<" belongs to "<<subnetPlusMask<<endl;
		return;
	}
	//ip不属于subnet
	else 
	cout<<" "<<ip<<" doesn't belong to "<<subnetPlusMask<<endl;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -