题解 | #识别有效的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;
}

全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务