读入字符串,按'~'进行拆分,如果没有找到'~'则地址非法;拆分成ip和mask后,先对mask进行检查,mask转成一个十进制的数,按位从最右边开始找第一个1,这个1的左边不能出现0;使用sscanf对点分十进制的ip进行拆分,得到a,b,c,d,通过对a、b的判断来对ip地址进行划分。
#include <stdio.h>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
enum addr_type
{
A_type, /*A类地址*/
B_type, /*B类地址*/
C_type, /*C类地址*/
D_type, /*D类地址*/
E_type, /*E类地址*/
I_type, /*非法地址*/
P_type, /*私有地址*/
O_type, /*其他地址*/
MAX_TYPE
};
void check_ip_type(const string& str, addr_type& type, bool& is_p_type)
{
unsigned long a,b,c,d;
if(str.find_first_not_of("0123456789.") != str.npos)
{
type = I_type;
return;
}
if(sscanf(str.c_str(), "%ld.%ld.%ld.%ld", &a,&b,&c,&d) != 4)
{
type = I_type;
return;
}
if(a > 255 || b>255 || c>255 || d>255)
{
type = I_type;
return;
}
if(a==0 || a==127)
{
type = O_type;
return;
}
if(a >= 1 && a<=126)
{
type=A_type;
}else if(a>=128 && a<=191)
{
type=B_type;
}else if(a>=192 && a<=223)
{
type=C_type;
}else if(a>=224 && a<=239)
{
type=D_type;
}else if(a>=240 && a<=255)
{
type=E_type;
}
if(a==10 || (a==172 && (b>=16 && b<=31)) || (a==192 && b==168))
{
is_p_type = true;
}
}
bool valid_mask(const string& str)
{
unsigned long a,b,c,d;
if(str.find_first_not_of("0123456789.") != str.npos)
return false;
if(sscanf(str.c_str(), "%ld.%ld.%ld.%ld", &a,&b,&c,&d) != 4)
return false;
if(a==255 && b==255 && c==255 && d==255)
return false;
if(a==0 && b==0 && c==0 && d==0)
return false;
if(a > 255 || b>255 || c>255 || d>255)
return false;
unsigned long mask = (a<<24) | (b << 16) | (c << 8) | d;
//从最低位的bit位查找为1的bit位,该位的左边不能出现0
bool found_bit1 = false;
while(mask)
{
if(found_bit1)
{
if((mask&1) == 0)
{
return false;
}
}
else
{
found_bit1 = ((mask&1)==1);
}
mask>>=1;
}
return true;
}
void fun(int count[], const string& str)
{
size_t offset = str.find('~');
if(offset != str.npos)
{
string ip = str.substr(0,offset);
string mask = str.substr(offset+1);
//检查mask是否非法;
if(valid_mask(mask))
{
addr_type type;
bool is_p_type = false;
check_ip_type(ip,type,is_p_type);
//相应的地址类型增加;
count[type]++;
//私有地址增加;
if(is_p_type)
{
count[P_type]++;
}
}
else
{
count[I_type]++;
}
}
else
{
count[I_type]++;
}
}
int main()
{
int count[MAX_TYPE]={0};
string str;
while(cin >> str)
fun(count, str);
//不输出其他类型的地址(0.*.*.*/127.*.*.*);
for(int i=0;i<MAX_TYPE-1;i++)
{
printf("%d ", count[i]);
}
return 0;
}
京公网安备 11010502036488号