题解 | java菜鸡的题解
识别有效的IP地址和掩码并进行分类统计
http://www.nowcoder.com/practice/de538edd6f7e4bc3a5689723a7435682
题目描述
请解析IP地址和对应的掩码,进行分类识别。要求按照A/B/C/D/E类地址归类,不合法的地址和掩码单独归类。
所有的IP地址划分为 A,B,C,D,E五类
A类地址1.0.0.0~126.255.255.255;
B类地址128.0.0.0~191.255.255.255;
C类地址192.0.0.0~223.255.255.255;
D类地址224.0.0.0~239.255.255.255;
E类地址240.0.0.0~255.255.255.255
私网IP范围是:
10.0.0.0~10.255.255.255
172.16.0.0~172.31.255.255
192.168.0.0~192.168.255.255
2. 私有IP地址和A,B,C,D,E类地址是不冲突的
输入描述:
多行字符串。每行一个IP地址和掩码,用~隔开。
输出描述:
notes:
具体实现(这部分摘自一个cpp大佬的,实在不想写了/233)
1、判断IP地址是否合法,如果满足下列条件之一即为非法地址
数字段数不为4
存在空段,即【192..1.0】这种
某个段的数字大于255
2、判断子网掩码是否合法,如果满足下列条件之一即为非法掩码
不是一个合格的IP地址
在二进制下,不满足前面连续是1,然后全是0
在二进制下,全为0或全为1
3、如何判断一个掩码地址是不是满足前面连续是1,然后全是0?
将掩码地址转换为Long类型,假设这个数为b。如果此时b为0,则为非法掩码
将b按位取反后+1。如果此时b为1,则b原来是二进制全1,非法掩码
代码如下:
import java.util.*;
public class Main{
private static Map<String,Integer> map = new HashMap<>();
private static String[] helpString = new String[]{"category_A","category_B","category_C","category_D","category_E","illegalIP","privateIP","other"};
public static void main(String[] args) {
for (int i = 0; i < helpString.length; i++) {//将各类的数目初始化为0
map.put(helpString[i], 0);
}
Scanner in = new Scanner(System.in);
while (in.hasNextLine()) {
String input = in.nextLine();
if(input.length() == 0) break;
String[] ipSegment = input.split("~");
String[] ipAddress = ipSegment[0].split("\\.");
String[] maskAddress = ipSegment[1].split("\\.");
// for (String address : ipAddress) {
// System.out.print(address + " ");
// }
// System.out.println();
// System.out.println(ipAddress.length);
//判断是否为非法的ip
boolean judgeIllegal = isIllegal(ipAddress, maskAddress);
if(!judgeIllegal){
map.put("illegalIP",map.get("illegalIP") + 1);
continue;
}
//判断子网掩码是否合法
boolean judgeMaskIP = isMask(maskAddress);
if(!judgeMaskIP){
map.put("illegalIP",map.get("illegalIP") + 1);
continue;
}
//判断ip是否为私有地址
boolean judgePrivate = isPrivate(ipAddress);
if(judgePrivate) map.put("privateIP",map.get("privateIP") + 1);
//判断ip的类别
String judgeCategory = judge_ip(ipAddress);
map.put(judgeCategory,map.get(judgeCategory) + 1);
}
System.out.println(map.get(helpString[0]) + " " + map.get(helpString[1]) + " " + map.get(helpString[2]) + " " +map.get(helpString[3]) + " "
+ map.get(helpString[4]) + " " + map.get(helpString[5]) + " " + map.get(helpString[6]));
in.close();
}
public static boolean isIllegal (String[]ipAddress, String[]maskAddress){
if (ipAddress.length != 4 || maskAddress.length != 4) return false;
for (String temp : ipAddress) {
long num = Long.parseLong(temp);
if (num < 0 || num > 255) return false;
}
return true;
}
//mask -1 | mask) == 0xFFFFFFFF ,如果是TRUE就是子网掩码,是FALSE就不是子网掩码。
public static boolean isMask (String[]maskAddress){
boolean flag = true;
if (maskAddress.length != 4) return false;
Long maskTemp = 0L;
for(int i=0; i < maskAddress.length; i++){
maskTemp = (maskTemp << 8) + Long.parseLong(maskAddress[i]);
}
//全0也判定为非法 掩码
if (maskTemp == 0) {
flag = false;
return flag;
}
//全为1 则不是子网掩码
Long tempMask = ~maskTemp + 1;
if (tempMask == 1) {
flag = false;
return flag;
}
// String judgeMask = Long.toBinaryString(maskTemp);
if(maskTemp <= 0 || maskTemp >=0XFFFFFFFFL || (((maskTemp ^ 0XFFFFFFFFL) + 1) | maskTemp)!= maskTemp){
flag = false;
return flag;
}
return flag;
}
//判断是否为私有地址
public static boolean isPrivate (String[]ipAddress){
long oneSegment = Long.parseLong(ipAddress[0]);
long twoSegment = Long.parseLong(ipAddress[1]);
if (oneSegment == 10) return true;
if (oneSegment == 172 && (twoSegment >= 16 && twoSegment <= 31)) return true;
if (oneSegment == 192 && twoSegment == 168) return true;
return false;
}
public static String judge_ip (String[]ipAddress){
long oneSegment = Long.parseLong(ipAddress[0]);
if (oneSegment >= 1 && oneSegment <= 126) return helpString[0];
if (oneSegment >= 128 && oneSegment <= 191) return helpString[1];
if (oneSegment >= 192 && oneSegment <= 223) return helpString[2];
if (oneSegment >= 224 && oneSegment <= 239) return helpString[3];
if (oneSegment >= 240 && oneSegment <= 255) return helpString[4];
return helpString[7]; //返回一个空字符串 不代表任何
}
}