题解 | #识别有效的IP地址和掩码并进行分类统计#
识别有效的IP地址和掩码并进行分类统计
https://www.nowcoder.com/practice/de538edd6f7e4bc3a5689723a7435682
const rl = require("readline").createInterface({ input: process.stdin });
var iter = rl[Symbol.asyncIterator]();
const readline = async () => (await iter.next()).value;
void (async function () {
const inputs = [];
const count = {
A: 0,
B: 0,
C: 0,
D: 0,
E: 0,
Err: 0,
private: 0,
};
while ((line = await readline())) {
inputs.push(line.split("~"));
}
inputs.forEach(([ip, mask]) => {
if (isIgnoreIp(ip)) {
// 忽略
}
// ip 或 掩码不合法,归类为错误
else if (!isValidMask(mask) || !isValidIp(ip)) {
count.Err++;
} else {
const result = getIpCate(ip);
count[result.cate]++;
count.private += result.isPrivate;
}
});
console.log(Object.values(count).join(" "));
})();
/**
* 【0.*.*.*】和【127.*.*.*】的IP地址不属于上述输入的任意一类,也不属于不合法ip地址,计数时忽略
*/
function isIgnoreIp(ip) {
return ["0", "127"].includes(ip.split(".")[0]);
}
/**
* 是否合法 ip
*/
function isValidIp(ip) {
return (
ip.split(".").filter((item) => item !== "" && item >= 0 && item <= 255)
.length === 4
);
}
/**
* 是否合法掩码
*/
// 子网掩码为 32 位二进制下前面是连续的1,然后全是0(注意二进制下全是1或者全是0均为非法子网掩码)
function isValidMask(mask) {
const binMask = mask.split(".").reduce((res, cur) => {
// 转为 8 位二进制
res += (+cur).toString(2).padStart(8, 0);
return res;
}, "");
const first0Index = binMask.indexOf("0");
const last1Inex = binMask.lastIndexOf("1");
// 都为 1
if (first0Index === -1) {
return false;
}
// 都为 0
if (Math.max(...binMask.split("")) === 0) {
return false;
}
// 0 后有 1
if (last1Inex > first0Index) {
return false;
}
return true;
}
/**
* 获取 ip 种类
*/
function getIpCate(ip) {
ip = ip.split(".").map((ip) => +ip);
const result = {
cate: "",
isPrivate: false,
};
// 地址分类
if (ip[0] >= 0 && ip[0] <= 126) {
result.cate = "A";
}
if (ip[0] >= 128 && ip[0] <= 191) {
result.cate = "B";
}
if (ip[0] >= 192 && ip[0] <= 223) {
result.cate = "C";
}
if (ip[0] >= 224 && ip[0] <= 239) {
result.cate = "D";
}
if (ip[0] >= 240 && ip[0] <= 255) {
result.cate = "E";
}
// 私网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
if (ip[0] === 10) {
result.isPrivate = true;
return result;
}
if (ip[0] === 172 && ip[1] >= 16 && ip[1] <= 31) {
result.isPrivate = true;
return result;
}
if (ip[0] === 192 && ip[1] === 168) {
result.isPrivate = true;
return result;
}
return result;
}
