题解 | #识别有效的IP地址和掩码并进行分类统计#
识别有效的IP地址和掩码并进行分类统计
https://www.nowcoder.com/practice/de538edd6f7e4bc3a5689723a7435682
const rl = require("readline").createInterface({
input: process.stdin,
output: process.stdout,
});
const inputs = [];
rl.on("line", (line) => {
inputs.push(line);
}).on("close", () => {
const res = countIP(inputs);
// 输出
const { A, B, C, D, E, Err, Pri } = res;
console.log(`${A} ${B} ${C} ${D} ${E} ${Err} ${Pri}`);
});
function countIP(inputs) {
let countMap = {
A: 0,
B: 0,
C: 0,
D: 0,
E: 0,
Err: 0,
Pri: 0,
};
for (let i = 0; i < inputs.length; i++) {
const temp = inputs[i].split("~");
let ip = temp[0],
code = temp[1];
const ipFirst = parseInt(ip.split(".")[0]);
// 0.*.*.* | 127.*.*.* 直接忽略
if (ipFirst === 0 || ipFirst === 127) {
continue;
} else {
// 判断掩码 code 是否合法
const binaryCode = codeTranstoBinary(code);
const zeroIndex = binaryCode.indexOf(0);
const oneIndex = binaryCode.lastIndexOf(1);
if (zeroIndex > -1 && oneIndex > -1 && zeroIndex > oneIndex) {
// 掩码合法之后判断ip是属于哪一类,还要注意是否属于私有
countMap = typeOfIP(ip, countMap);
// 私网
validatePrivateIp(ip) && countMap["Pri"]++;
} else {
countMap.Err++;
}
}
}
return countMap;
}
// 255.255.255.255 => 11111111.11111111.11111111.11111111
function codeTranstoBinary(code) {
let res = [];
const codeArr = code.split(".");
for (let i = 0; i < codeArr.length; i++) {
const binary = parseInt(codeArr[i], 10).toString(2);
res[i] = "00000000".slice(0, 8 - binary.length) + binary;
}
return res.join(".");
}
function typeOfIP(ip, map) {
let res = map;
if (validateIp(ip)) {
const ipFirst = parseInt(ip.split(".")[0]);
// A
if (ipFirst >= 1 && ipFirst <= 126) {
res["A"]++;
}
// B
else if (ipFirst >= 128 && ipFirst <= 191) {
res["B"]++;
}
// C
else if (ipFirst >= 192 && ipFirst <= 223) {
res["C"]++;
}
// D
else if (ipFirst >= 224 && ipFirst <= 239) {
res["D"]++;
}
// E
else if (ipFirst >= 240 && ipFirst <= 255) {
res["E"]++;
}
} else {
res.Err++;
}
return res;
}
function validateIp(ip) {
const re =
/(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)){3}/;
return re.test(ip);
}
function validatePrivateIp(ip) {
let validate = false;
const ipFirst = ip.split(".")[0];
if (ipFirst === "10") {
validate = /10(\.(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)){3}/.test(ip);
}
if (ipFirst === "172") {
validate =
/172\.(1[6-9]|2\d|3[0-1])(\.(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)){2}/.test(
ip
);
}
if (ipFirst === "192") {
validate = /192\.168(\.(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)){2}/.test(ip);
}
return validate;
}
难度:⭐⭐⭐⭐
题目:
输入一组类似 ”ip~掩码“,要找出有效的掩码和ip,并且给分类,最后输出每种分类的个数。
有 A、B、C、D、E、错误的掩码和ip、私网ip这7种分类,给出这组输入每种分类的个数。
关键点:
- 0.*.*.*|127.*.*.* 这两种ip直接忽略不计数
- 判断掩码是否有效
- 判断ip是否有效
- 判断ip是否是私网ip
难点:
- 怎么判断掩码是否有效?
- 子网掩码为二进制下前面是连续的1,然后全是0。 这是判断子网掩码的关键,起初我就没有理解错题目。
- 根据上一点,所以掩码不能全是0,不能全是1,同时第一个0的下标比最后一个1的下标大,那这个掩码就是合法的。
- 怎么判断ip是否有效?
- 我用的是正则表达式,这题不用正则也行,我就单纯想用正则解题。
- ip:0.255.255.255,有四段,每段最多三位数,分情况讨论每种情况写出对应的正则,最后合在一起。
- [1-9]?\d|1\d{2}|2[0-4]\d|25[0-5] 这是一段的五种情况,0 | 10 | 192 | 245 | 255 对应的五种情况,\. 匹配小数点,合成四段。XXX.XXX.XXX.XXX
- 判断私网ip有效,就是取ip的第一段,然后用对应的正则判断是否是有效的私网ip即可。
步骤:
理解了上面的难点,这道题就简单了,就是按:
1、遇到ip第一段是0 和 127就直接略过
2、判断掩码是否有效,无效就Err+1,有效就判断ip是否有效
3、ip有效就判断是哪一类的ip,对应的类型计数+1
4、ip有效再判断是不是属于私网ip,是私网就Pri+1
5、如果ip无效就Err+1
这道题属于不会之前难,会后不难,…… 难点还是上面提到的那两个难点,过程中的细节小心一点即可。
掌握正则的分析与拼凑
