上图引用文章:http://t.csdn.cn/Jq59L

//(ip地址)A类地址从1.0.0.0(网络地址)~126.255.255.255(网络地址)(ip地址开头(网络地址),需要判断:是4个数字组成的IP地址且每个数字在[0,255],且不是0开头或者127开头。)
/*实例1中的:1.0.0.1(网络地址)~255.0.0.0(子网掩码)
  1.0.0.1(网络地址),需要判断:是4位IP地址,且不是0开头或者127开头。)
  255.0.0.0(子网掩码),需要判断:是4个数字组成的IP地址且每个数字在[0,255],不能全是1(255.255.255.255)也不能全是0(0.0.0.0),且子网掩码为二进制下前面是连续的1,然后全是0。) 
  (255.0.0.0(子网掩码)对应二进制:11111111.00000000.00000000.00000000);  
*/
 /*找到32位无符号字符编码中,第一个0的位置和最后一个1的位置,如果最后一个1的位置+1得到第一个零的位置。
 代表这是一段连续的1,后面拼接了一段连续的0。
 */

//最后分类判断范围。
/*注意:
1.分割:in.nextLine().split("\\.");
2.while循环终结:
 	if(IPAndMask[0].equals("end")){
                break;//循环输入终结
            }
3.//int num[] = new int[7];//如果这样写不赋值,有的地方是空值,就会导致打印的时候报错。
  int num[] = new int[]{0,0,0,0,0,0,0}; //统计A0、B1、C2、D3、E4、错误IP地址或错误掩码5、私有IP的个数6,之间以空格隔开。
4.使用StringBulider进行拼接更方便:
String[] maskTable = mask.split("\\.");
StringBuilder strBuilder = new StringBuilder();//得到32位32位无符号字符编码,即掩码字符串
            for (int i = 0; i < maskTable.length; i++) {
                maskTable[i] = Integer.toBinaryString(Integer.parseInt(maskTable[i]));//字符串转换成整数int型,再转换成二进制数的字符串。
                if(maskTable[i].length()<8){//检查不足8位数,要补足8位
                    for (int j = 0; j < 8-maskTable[i].length()+1; j++) {
                        strBuilder.append("0");//先在空字符串中补0
                    }//然后在后面加上二进制数的字符串
                    strBuilder.append(maskTable[i]);
                }else {//正好8位数(//小于255可以确定二进制字符串最多只有8位。)
                    strBuilder.append(maskTable[i]);
                }
            }

*/

import java.util.Scanner;

public class Main{
public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        //int num[] = new int[7];//如果这样写不赋值,有的地方是空值,就会导致打印的时候报错。
        int num[] = new int[]{0,0,0,0,0,0,0}; //统计A0、B1、C2、D3、E4、错误IP地址或错误掩码5、私有IP的个数6,之间以空格隔开。
        while (in.hasNextLine()) {
            String[] IPAndMask = in.nextLine().split("~");//ip地址和对应掩码
            if(IPAndMask[0].equals("end")){
                break;//循环输入终结
            }

            String[] IPAddressStart = IPAndMask[0].split("\\.");//ip地址开头
            String[] IPAddressEnd = IPAndMask[1].split("\\.");//ip地址结尾
/*注意:
1. 类似于【0.*.*.*】和【127.*.*.*】的IP地址不属于上述输入的任意一类,也不属于不合法ip地址,计数时请忽略
2. 私有IP地址和A,B,C,D,E类地址是不冲突的* */
            //类似于【0.*.*.*】和【127.*.*.*】忽略,这个条件要放在最前面,否则错误掩码会统计多
            if (IPAddressStart[0].equals("0")||IPAddressStart[0].equals("127")
                ||IPAddressEnd[0].equals("0")||IPAddressEnd[0].equals("127")){
                continue;//跳过
            }
            if(!isValidMask(IPAndMask[1])){
                //先判断IP地址的掩码是否有效。因为判断掩码的方法中,会先判断IP地址是否有效。
                num[5]++;//ip地址结尾是错误IP地址或错误掩码5
                continue;//跳过
            }else {//ip地址结尾是正确的IP地址或掩码
                if(!isValidIPAddress(IPAndMask[0])){
                    num[5]++;//ip地址开头是错误IP地址
                    continue;//跳过
                }else {//ip地址开头是合法的IP地址,且结尾都是合法的IP地址或掩码。可以统计A0、B1、C2、D3、E4、私有IP的个数6。
                    int IPNumber[] = new int[]{0,0,0,0,0,0,0,0};//8个字符串:从1.0.0.0(ip地址开头)到126.255.255.255(ip地址结尾)
                    for (int i = 0; i < 8; i++) {//转换8个字符串为8个整数类型。
                        if(i<4){
                            IPNumber[i]=Integer.parseInt(IPAddressStart[i]);
                        }else{
                            IPNumber[i]=Integer.parseInt(IPAddressEnd[i-4]);
                        }
                    }
                    if (IPNumber[0] >= 1 && IPNumber[0] <= 126) {
                        num[0]++;//A类
                        if (IPNumber[0] == 10) {
                            num[6]++;//存在私有IP
                        }
                    } else if (IPNumber[0] >= 128 && IPNumber[0] <= 191) {
                        num[1]++;//B类
                        if (IPNumber[0] == 172 && IPNumber[1] >= 16 && IPNumber[1] <=31) {
                            num[6]++;//存在私有IP
                        }
                    } else if (IPNumber[0] >= 192 && IPNumber[0] <= 223) {
                        num[2]++;//C类
                        if (IPNumber[0] == 192 && IPNumber[1] == 168) {
                            num[6]++;//存在私有IP
                        }
                    } else if (IPNumber[0] >= 224 && IPNumber[0] <= 239) {
                        num[3]++;//D类
                    } else if (IPNumber[0] >= 240 && IPNumber[0] <= 255) {
                        num[4]++;//E类
                    } else {
                        num[5]++;//错误IP地址或错误掩码
                    }
                }
            }
        }
        for (int i = 0; i < num.length; i++) {
            //输出一行:统计A、B、C、D、E、错误IP地址或错误掩码、私有IP的个数,之间以空格隔开。
            if(i==num.length-1){
                System.out.print(num[i]);
            }else {
                System.out.print(num[i]+" ");
            }
        }
    }


    //检验ip地址是否合法
    private static boolean isValidIPAddress (String ip){
        String[] ipTable = ip.split("\\.");
        if(ipTable.length != 4){//四位
            return false;
        }else {
            for (String s : ipTable){//小于255可以确定二进制字符串最多只有8位。
                if (Integer.parseInt(s)<0 || Integer.parseInt(s)>255){
                    return false;
                }
            }
            return true;
        }
    }
    /*子网掩码为二进制下前面是连续的1,然后全是0。(例如:255.255.255.32就是一个非法的掩码)
        (注意二进制下全是1或者全是0均为非法子网掩码)*/
    //检验掩码是否合法
    public static boolean isValidMask(String mask){

        /*if(s[1]=="255.255.255.255"||s[1]=="0.0.0.0"){
            num[5]++;
            continue;
        }*/
        if(!isValidIPAddress(mask)){//检验IP地址的掩码,首先检验IP地址是否合法的。
            return false;
        } else if (mask=="255.255.255.255"||mask=="0.0.0.0") {//(注意二进制下全是1或者全是0均为非法子网掩码)
            return false;
        } else {//检验IP地址的掩码是否是连续的1,然后全是0
            String[] maskTable = mask.split("\\.");
            StringBuilder strBuilder = new StringBuilder();//得到32位32位无符号字符编码,即掩码字符串
            for (int i = 0; i < maskTable.length; i++) {
                maskTable[i] = Integer.toBinaryString(Integer.parseInt(maskTable[i]));//字符串转换成整数int型,再转换成二进制数的字符串。
                if(maskTable[i].length()<8){//检查不足8位数,要补足8位
                    for (int j = 0; j < 8-maskTable[i].length()+1; j++) {
                        strBuilder.append("0");//先在空字符串中补0
                    }//然后在后面加上二进制数的字符串
                    strBuilder.append(maskTable[i]);
                }else {//正好8位数(//小于255可以确定二进制字符串最多只有8位。)
                    strBuilder.append(maskTable[i]);
                }
            }
             /*找到32位无符号字符编码中,第一个0的位置和最后一个1的位置,如果最后一个1的位置+1得到第一个零的位置。
            代表这是一段连续的1,后面拼接了一段连续的0。*/
            if(strBuilder.lastIndexOf("1")+1==strBuilder.indexOf("0")){
                return true;//是连续的1,然后全是0
            }else{
                return false;
            }
        }
    }




}

178.136.80.23~255.0.0.0

200.65.151.23~255.255.4.255

178.58.187.150~255.30.255.255

194.102.70.40~255.0.0.0

199.165.138.223~255.0.0.0

170.224.161.237~255.255.0.0

52.183.63.36~255.255.0.0

201.139.83.68~255.0.0.0

6.13.249.184~255.255.0.0

98.230.27.222~255.0.0.0

201.67.65.114~255.255.255.0

227.188.181.97~255.0.0.0

154.122.129.76~255.255.255.0