import java.util.*;
public class Main {
// 记录统计结果
public static int A = 0;
public static int B = 0;
public static int C = 0;
public static int D = 0;
public static int E = 0;
public static int Err = 0;
public static int Pri = 0;
// 主函数
public static void main(String[] args) {
// 标准输入
Scanner input = new Scanner(System.in);
// 循环获取ip地址和子网掩码
while (input.hasNextLine()) {
String ip_subnetMask = input.nextLine();
// 拆分
String[] datas = ip_subnetMask.split("~");
String ip = datas[0];
String subnetMask = datas[1];
// 解析本组数据
parseData(ip, subnetMask);
}
// 数据解析完成,输出统计结果
System.out.println(A+" "+B+" "+C+" "+D+" "+E+" "+Err+" "+Pri);
}
// 解析输入数据
public static void parseData(String ip, String subnetMask) {
// 预处理
if (ip.startsWith("0.") || ip.startsWith("127.")) return;
// 先解析子网掩码
if (!parse_subnetMask(subnetMask)) return;
// 子网掩码合法时再解析ip地址
if (!parse_ip(ip)) return;
}
// 解析子网掩码
public static boolean parse_subnetMask(String subnetMask) {
// 使用正则表达式初步过滤
if (!subnetMask.matches("[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+")) {
Err++;
return false;
}
// 二次过滤
// 先获取子网掩码的二进制形式
String[] nums = subnetMask.split("\\."); // 分割
StringBuffer maskBinary = new StringBuffer(); // 创建容器
// 拼接二进制字符串
for (String num : nums) {
// 转十进制数字
int n = Integer.parseInt(num);
// 转二进制字符串
String tempBinary = Integer.toBinaryString(n);
// 将字符串补足至8位
while (tempBinary.length() < 8) {
tempBinary = "0" + tempBinary;
}
// 拼接
maskBinary.append(tempBinary);
}
// 判断其二进制形式是否合法
if (!maskBinary.toString().matches("[1]+[0]+")) {
Err++;
return false;
}
// 子网掩码校验通过
return true;
}
// 解析ip地址
public static boolean parse_ip(String ip) {
// 使用正则表达式初步过滤
if (!ip.matches("[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+")) {
Err++;
return false;
}
// 二次过滤
String[] nums = ip.split("\\.");
for (String num : nums) {
// 子串长度不是1但是以0开头
if (num.length() != 1 && num.charAt(0) == '0') {
Err++;
return false;
}
// 数值越界
int n = Integer.parseInt(num);
if (n < 0 || n > 255) {
Err++;
return false;
}
}
// ip地址校验合法,则判断其分类
int firstNum = Integer.parseInt(nums[0]);
// 判断ip地址分类
boolean isA = 1 <= firstNum && firstNum <= 126 ? true : false;
boolean isB = 128 <= firstNum && firstNum <= 191 ? true : false;
boolean isC = 192 <= firstNum && firstNum <= 223 ? true : false;
boolean isD = 224 <= firstNum && firstNum <= 239 ? true : false;
boolean isE = 240 <= firstNum && firstNum <= 255 ? true : false;
// 统计ip地址分类
if (isA) A++;
if (isB) B++;
if (isC) C++;
if (isD) D++;
if (isE) E++;
// 判断ip地址是否为私有地址
int secondNum = Integer.parseInt(nums[1]);
// 判断私有地址分类
boolean isPri_1 = firstNum == 10 ? true : false;
boolean isPri_2 = (firstNum == 172 && 16 <= secondNum && secondNum <= 31) ? true : false;
boolean isPri_3 = (firstNum == 192 && secondNum == 168) ? true : false;
// 当前ip地址满足其中一种则为私有地址
if (isPri_1 || isPri_2 || isPri_3) Pri++;
// ip地址解析完成
return true;
}
}