有效ipv4地址

/*
题目描述
请解析IP地址和对应的掩码,进行分类识别。要求按照A/B/C/D/E类地址归类,不合法的地址和掩码单独归类。

所有的IP地址划分为 A,B,C,D,E五类

A类地址1.0.0.0~126.255.255.255;

B类地址128.0.0.0~191.255.255.255;

C类地址192.0.0.0~223.255.255.255;

D类地址224.0.0.0~239.255.255.255;

E类地址240.0.0.0~255.255.255.255


私网IP范围是:

10.0.0.0~10.255.255.255

172.16.0.0~172.31.255.255

192.168.0.0~192.168.255.255


子网掩码为二进制下前面是连续的1,然后全是0。(例如:255.255.255.32就是一个非法的掩码)

输入描述:
多行字符串。每行一个IP地址和掩码,用~隔开。

输出描述:
统计A、B、C、D、E、错误IP地址或错误掩码、私有IP的个数,之间以空格隔开。

示例1
输入
10.70.44.68~255.254.255.0
1.0.0.1~255.0.0.0
192.168.0.2~255.255.255.0
19..0.~255.255.255.0
输出
1 0 1 0 0 2 1
*/
#include<iostream>
using namespace std;
unsigned int IP_NUM(unsigned int a, unsigned int  b, unsigned int c, unsigned int d) 
{	
	return  ((a)*256*256*256+(b)*256*256+(c)*256+d);
} 
int ip_is_valid(string ip, unsigned int &ret)
{
	int len = ip.size();
	int num = 0;
	int dot_cnt = 0;
	int num_cnt = 0;
	int num_flag = 0;
	int a[4] = {0,0,0,0};
	for(int i=0; i<len; ++i)
	{
		if(dot_cnt > 3)
		{
			return 0;
		}
		if(ip[i]>='0' && ip[i]<='9')
		{
			num = num*10 + (ip[i]-'0');
			num_cnt++;
			if(num_cnt > 3 || num > 255)
			{
				return 0;
			}
			num_flag = 1;
			
		}
		else if(ip[i] == '.')
		{
			if(i<len-1 && num_flag == 1)
			{
				a[dot_cnt] = num;
				dot_cnt++;
				num_cnt=0;
				num = 0;
				num_flag = 0;
			}
			else
			{
				return 0;
			}
		}
		else
		{
			return 0;
		}
	}
	if(dot_cnt < 3)
	{
		return 0;
	}
	a[3] = num;
	ret = IP_NUM(a[0], a[1], a[2], a[3]);
	return 1;
}

int mask_is_valid(string str)
{
	unsigned int mask = 0;
	int ret = ip_is_valid(str, mask);
	if(ret == 0 || str=="255.255.255.255") //出题者认为255.255.255.255不是合法掩码
	{
		return 0;
	}
	int flag = 0;
	while(mask > 0)
	{
		if((mask & 1) == 1)
		{
			flag = 1;
		}
		else if(flag == 1)
		{	
			return 0;
		}
		mask = mask >> 1;
	}
	return flag;
}

int ip_type(unsigned int ip)
{
	//1.0.0.0~126.255.255.255
	if(IP_NUM(1,0,0,0)<=ip && ip<=IP_NUM(126,255,255,255) )
	{
		return 0;
	}
	//128.0.0.0~191.255.255.255
	if(IP_NUM(128,0,0,0)<=ip && ip<=IP_NUM(191,255,255,255) )
	{
		return 1;
	}
	//192.0.0.0~223.255.255.255;
	if(IP_NUM(192,0,0,0)<=ip && ip<=IP_NUM(223,255,255,255) )
	{
		return 2;
	}
	//224.0.0.0~239.255.255.255
	if(IP_NUM(224,0,0,0)<=ip && ip<=IP_NUM(239,255,255,255) )
	{
		return 3;
	}
    //240.0.0.0~255.255.255.255
    if(IP_NUM(240,0,0,0)<=ip && ip<=IP_NUM(255,255,255,255) )
	{
		return 4;
	}
	return 5;
}

int is_private_ip(unsigned int ip)
{
	//10.0.0.0~10.255.255.255
	if(IP_NUM(10,0,0,0)<=ip && ip<=IP_NUM(10,255,255,255) )
	{
		return 1;
	}
	//172.16.0.0~172.31.255.255
	if(IP_NUM(172,16,0,0)<=ip && ip<=IP_NUM(172,31,255,255) )
	{
		return 1;
	}
	//192.168.0.0~192.168.255.255
	if(IP_NUM(192,168,0,0)<=ip && ip<=IP_NUM(192,168,255,255) )
	{
		return 1;
	}
	return 0;
}

int main()
{
	int a[7]={0,0,0,0,0,0,0};
	string str;
	while(cin>>str)
	{
		int pos = str.find("~");
		string ip = str.substr(0,pos);
		string mask = str.substr(pos+1);
		unsigned int ip_num = 0;
		if(ip_is_valid(ip, ip_num) == 0)
		{
			a[5] += 1;
            continue ;
		}
        else
        {
            if(mask_is_valid(mask) == 0)
		    {
			    a[5] += 1;
                continue ;
		    }
            int i = ip_type(ip_num);
            if(i < 5)
		        a[i] += 1;
		    if(is_private_ip(ip_num) == 1)
		    {
			    a[6] += 1;
		    }
        }
	}
	cout<<a[0]<<" "<<a[1]<<" "<<a[2]<<" "<<a[3]<<" "<<a[4]<<" "<<a[5]<<" "<<a[6]<<endl;
	return 0;
}











评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值