识别有效的IP地址和掩码并进行分类统计
题目描述
请解析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
子网掩码为前面是连续的1,然后全是0。(例如:255.255.255.32就是一个非法的掩码)
本题暂时默认以0开头的IP地址是合法的,比如0.1.1.2,是合法地址
输入描述:
多行字符串。每行一个IP地址和掩码,用~隔开。
输出描述:
统计A、B、C、D、E、错误IP地址或错误掩码、私有IP的个数,之间以空格隔开。
输入例子:
10.70.44.68~255.254.255.0
1.0.0.1~255.0.0.0
192.168.0.2~255.255.255.0
19..0.~255.255.255.0
输出例子:
1 0 1 0 0 2 1
接下来提出的坑,都是自己踩过的,编程会用到。
具体就是如32, Integer.parseInt(string),以后获得的String为100000,而我们想要的应该是00100000这样的字符串
其他的有问题看注释就行,另外输入输出实在是一门很“高深”的学问,难了我好久,错误提交好多次。还是喜欢leetcode
import java.util.Scanner;
/**
* Created by loveqh on 2016/10/12.
*/
public class DetectIpAndMask {
// A、B、C、D、E、错误IP地址或错误掩码、私有IP的个数
/**
* 返回
* 0:A
* 1:B
* 2:C
* 3:D
* 4:E
*
* @param str
* @return
*/
public static int classRifyIp(String str) {
String[] ips = str.split("\\.");
int[] ipInts = strings2Num(ips);
int ipFirst = ipInts[0];
if (ipFirst >= 1 && ipFirst <= 126)
return 0;
if (ipFirst >= 128 && ipFirst <= 191)
return 1;
if (ipFirst >= 192 && ipFirst <= 223)
return 2;
if (ipFirst >= 224 && ipFirst <= 239)
return 3;
if (ipFirst >= 240 && ipFirst <= 255)
return 4;
return Integer.MAX_VALUE;
}
/**
* 如果为5则表示错误,否则就有效的掩码
*
* @param str
* @return
*/
public static int classRifyMask(String str) {
if (!isValidMask(str)) {
return 5;
}
return Integer.MAX_VALUE;
}
/**
* 如果是6则表示是私有IP地址
*
* @param str
* @return
*/
public static int classRifyPrivate(String str) {
if (isPrivateIp(str))
return 6;
return Integer.MAX_VALUE;
}
/**
* 判断字符串是够是有效的子网掩码
*
* @param string
* @return
*/
private static boolean isValidMask(String string) {
String str = num2BinaryString(string);
int lastOneIndex = str.lastIndexOf("1");
if (lastOneIndex == str.length() - 1) return false;
if (lastOneIndex > 0) {
char[] rest = str.substring(0, lastOneIndex).toCharArray();
for (int i = 0; i < rest.length; i++) {
if (rest[i] == '0') {
return false;
}
}
}
return true;
}
/**
* 判断字符串是否私有IP地址
*
* @param str
* @return
*/
private static boolean isPrivateIp(String str) {
String[] ips = str.split("\\.");
int[] ipInts = strings2Num(ips);
int ipFirst = ipInts[0];
int ipSecond = ipInts[1];
if (ipFirst == 10)
return true;
if (ipFirst == 172 && ipSecond >= 16 && ipSecond <= 31)
return true;
if (ipFirst == 192 && ipSecond == 168)
return true;
return false;
}
/**
* 是否为有效的ip地址
*
* @param str
* @return
*/
private static boolean isValidIp(String str) {
String[] strings = str.split("\\.");
for (String string : strings) {
if ("".equals(string)) {
return false;
}
Integer integer = Integer.parseInt(string);
if (integer < 0 || integer > 255) {
return false;
}
}
return true;
}
/**
* 将ip地址字符串转换为01序列字符串。
*
* @param str
* @return
*/
private static String num2BinaryString(String str) {
String[] strings = str.split("\\.");
StringBuffer sb = new StringBuffer();
for (String string : strings) {
String temp = Integer.toBinaryString(Integer.parseInt(string.trim()));
int i = 8 - temp.length();
for (int k = 0; k < i; k++) {
sb.append('0');
}
sb.append(temp);
}
return sb.toString();
}
/**
* ip字符数组转换为数字数组
*
* @param ips
* @return
*/
private static int[] strings2Num(String[] ips) {
int[] res = new int[ips.length];
int i = 0;
for (String str : ips) {
res[i] = Integer.parseInt(str);
i++;
}
return res;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int[] res = new int[7];
String ipMask = null;
while (sc.hasNext()) {
ipMask = sc.nextLine();
String[] ipMasks = ipMask.split("~");
String ip = ipMasks[0];
String mask = ipMasks[1];
int maskInt = DetectIpAndMask.classRifyMask(mask);
if (maskInt == Integer.MAX_VALUE) {
if (isValidIp(ip)) {
int ipInt = DetectIpAndMask.classRifyIp(ip);
if (ipInt != Integer.MAX_VALUE) {
res[ipInt]++;
}
int privateInt = DetectIpAndMask.classRifyPrivate(ip);
//私有IP地址
if (privateInt != Integer.MAX_VALUE) {
res[privateInt]++;
}
} else {
res[5]++;
}
} else {
res[maskInt]++;
}
}
System.out.println(res[0] + " " + res[1] + " " + res[2] + " " + res[3] + " " + res[4] + " " + res[5] + " " + res[6]);
}
}