题目描述
- 请解析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就是一个非法的掩码)
注意二进制下全是1或者全是0均为非法
注意:
- 类似于【0...】和【127...】的IP地址不属于上述输入的任意一类,也不属于不合法ip地址,计数时可以忽略
- 私有IP地址和A,B,C,D,E类地址是不冲突的
- 输入描述:
多行字符串。每行一个IP地址和掩码,用~隔开。 - 输出描述:
统计A、B、C、D、E、错误IP地址或错误掩码、私有IP的个数,之间以空格隔开。 - 示例1
输入
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
思路
思路:
本题的解决难点在如何判断是否是错误掩码,和如何利用各种异或运算,移位运算。
1,将ip地址转换为十进制数
2,判断是否是私有ip
3,判断掩码
完整代码
package org.lht.boot.lang.suanfa;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
/**
* @author haitao.li
* @description: 题目描述
* 请解析IP地址和对应的掩码,进行分类识别。要求按照A/B/C/D/E类地址归类,不合法的地址和掩码单独归类。
* <p>
* 所有的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
* <p>
* 私网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
* <p>
* <p>
* 子网掩码为二进制下前面是连续的1,然后全是0。(例如:255.255.255.32就是一个非法的掩码)
* 注意二进制下全是1或者全是0均为非法
* <p>
* 注意:
* 1. 类似于【0.*.*.*】和【127.*.*.*】的IP地址不属于上述输入的任意一类,也不属于不合法ip地址,计数时可以忽略
* 2. 私有IP地址和A,B,C,D,E类地址是不冲突的
* <p>
* 输入描述:
* 多行字符串。每行一个IP地址和掩码,用~隔开。
* <p>
* 输出描述:
* 统计A、B、C、D、E、错误IP地址或错误掩码、私有IP的个数,之间以空格隔开。
* <p>
* 示例1
* 输入
* <p>
* 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
* 输出
* <p>
* 1 0 1 0 0 2 1
* @date 2021/4/26 9:37
*/
public class Huawei识别有效ip地址和掩码并进行统计 {
/**
* 思路:
* 本题的解决难点在如何判断是否是错误掩码
* <p>
* 1,将ip地址转换为十进制数
* 2,判断是否是私有ip
* 3,判断掩码
*/
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String ipStr;
int A = 0, B = 0, C = 0, D = 0, E = 0, Error = 0, P = 0;
while (!(ipStr = reader.readLine()).equals("")) {
int index = ipStr.indexOf("~");
long ip = ipToNum(ipStr.substring(index + 1));
//^异或运算:运算规则:0^0=0; 0^1=1; 1^0=1; 1^1=0
//|按位或运算符: 运算规则:0|0=0; 0|1=1; 1|0=1; 1|1=1
//判断是否是错误掩码(((ip ^ 0XFFFFFFFFL) + 1) | ip) != ip)==11110000^11111111=00001111+1=00010000|11110000=11110000
if (ip <= 0 || ip >= 0XFFFFFFFFL || (((ip ^ 0XFFFFFFFFL) + 1) | ip) != ip) {
Error += 1;
continue;
}
ip = ipToNum(ipStr.substring(0, index));
long partOfIP = ip >> 24;
if (ip <= 0L || ip >= 0XFFFFFFFFL) {
Error += 1;
} else if (partOfIP >= 1 && partOfIP <= 126) {
A += 1;
if (partOfIP == 10) {
P += 1;
}
} else if (partOfIP >= 128 && partOfIP <= 191) {
B += 1;
if (ip >> 20 == 0XAC1) {
P += 1;
}
} else if (partOfIP >= 192 && partOfIP <= 223) {
C += 1;
if (ip >> 16 == 0XC0A8) {
P += 1;
}
} else if (partOfIP >= 224 && partOfIP <= 239) {
D += 1;
} else if (partOfIP >= 240 && partOfIP <= 255) {
E += 1;
}
}
System.out.println(A + " " + B + " " + C + " " + D + " " + E + " "
+ Error + " " + P);
}
public static long ipToNum(String ip) {
long num = 0;
int flag = 1, temp = 0;
char[] chars = ip.toCharArray();
for (int i = 0; i < chars.length; i++) {
if (chars[i] == '.') {
num = num << 8 | temp;
temp = 0;
flag++;
continue;
}
if (flag >= 2) {
return -1;
}
if (chars[i] >= '0' && chars[i] <= '9') {
temp = temp * 10 + chars[i] - '0';
flag = 0;
} else {
flag = 3;
break;
}
}
if (flag >= 2) {
return -1;
}
num = num << 8 | temp;
return num;
}
}