//#include <bits/stdc++.h>
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
using namespace std;
//判断ip
/*判断IP地址是否合法,如果满足下列条件之一即为非法地址
数字段数不为4
存在空段,即【192..1.0】这种
某个段的数字大于255
*/
bool judgeIP(string s){
int count = 0;
stringstream iss(s);
string tmp = "";
while(getline(iss, tmp, '.')){
if(++count > 4 || tmp.empty() || stoi(tmp) > 255){
return false;
}
}
return count == 4;
}
//判断是否私有
bool isPrivate(string s){
stringstream iss(s);
string tmp = "";
vector<int> vec;
while(getline(iss, tmp, '.')){
vec.push_back(stoi(tmp));
}
if(vec[0] == 10) return true;
if(vec[0] == 172 && (vec[1] >= 16 && vec[1] <= 31)) return true;
if(vec[0] == 192 && vec[1] == 168) return true;
return false;
}
//判断掩码
/*
判断子网掩码是否合法,如果满足下列条件之一即为非法掩码
不是一个合格的IP地址
在二进制下,不满足前面连续是1,然后全是0
在二进制下,全为0或全为1
如何判断一个掩码地址是不是满足前面连续是1,然后全是0?
将掩码地址转换为32位无符号整型,假设这个数为b。如果此时b为0,则为非法掩码
将b按位取反后+1。如果此时b为1,则b原来是二进制全1,非法掩码
如果b和b-1做按位与运算后为0,则说明是合法掩码,否则为非法掩码
*/
bool judgeMask(string s){
stringstream iss(s);
string tmp = "";
unsigned int val = 0;
while(getline(iss, tmp, '.')){
val = (val << 8) + stoi(tmp); //拿到子网掩码的32位无符号整形值
}
//cout << "val" << val << endl;
if(val == 0) return false; //全为0
if(~val + 1 == 1) return false; //全为1
if((val | (val - 1)) == 0xFFFFFFFF) return true; //全面连续1,后面连续0
//if((val & (val - 1)) == 0) return true;
return false;
}
int main(){
string str = "";
int a = 0, b = 0, c = 0, d = 0, e = 0, err = 0, p = 0;
while(cin >> str){
stringstream iss(str);
string tmp = "";
vector<string> vec;
while(getline(iss, tmp, '~')){
vec.push_back(tmp);//按行读取输入,根据字符‘~’ 将IP地址与子网掩码分开
}
//cout<<vec[0]<<" "<<vec[1]<<endl;
int first = stoi(vec[0].substr(0, vec[0].find_first_of('.')));
//查看子网掩码是否合法
if((first != 127) && (!judgeIP(vec[0]) || !judgeMask(vec[1]))) err++; //多加first != 127的判断(否则会多加一次err)
else{//合法,则继续检查IP地址
//查看IP地址是否合法
if(!judgeIP(vec[0])) err++;//非法,相应统计项+1
else{//合法,查看IP地址属于哪一类,是否是私有ip地址;相应统计项+1
if(isPrivate(vec[0])) p++;
if(first == 0 || first == 127) continue;
else if(first >= 1 && first <= 126) a++;
else if(first >= 128 && first <= 191) b++;
else if(first >= 192 && first <= 223) c++;
else if(first >= 224 && first <= 239) d++;
else if(first >= 240 && first <= 255) e++;
}
}
}
cout << a << " " << b << " " << c << " " << d << " " << e << " " << err << " " << p << endl;
return 0;
}