题解 | #识别有效的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
这道题属于不会之前难,会后不难,…… 难点还是上面提到的那两个难点,过程中的细节小心一点即可。
掌握正则的分析与拼凑