上图引用文章: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