HJ18 识别有效的IP地址和掩码并进行分类统计

187 阅读3分钟

Problem: HJ18 识别有效的IP地址和掩码并进行分类统计

题目描述

描述

请解析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均为非法子网掩码)

注意:

  1. 类似于【0...】和【127...】的IP地址不属于上述输入的任意一类,也不属于不合法ip地址,计数时请忽略

  2. 私有IP地址和A,B,C,D,E类地址是不冲突的 数据范围:1n10001≤n≤1000

输入描述:

多行字符串。每行一个IP地址和掩码,用~隔开。 请参考帖子www.nowcoder.com/discuss/276…

输出描述:

统计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地址和掩码是否合法:
  • IP地址和掩码的每个部分(以点分十进制表示)都在合法范围内。
    - 掩码的二进制形式前面是连续的1,然后全是0。
    - IP地址和掩码不能全是0或全是1。
  1. 根据IP地址的范围进行分类识别: - 如果IP地址在A类地址范围内,则归类为A类地址。
    - 如果IP地址在B类地址范围内,则归类为B类地址。
    - 如果IP地址在C类地址范围内,则归类为C类地址。
    - 如果IP地址在D类地址范围内,则归类为D类地址。
    - 如果IP地址在E类地址范围内,则归类为E类地址。
    - 如果IP地址在私网IP范围内,则归类为私网地址。
    - 如果IP地址不在以上范围内,则归类为非法地址。
  2. 返回分类结果。

代码

function parseIPAndMask(ip, mask){
    //将ip和掩码转换为二进制
    const ipBinary = ip.split('.').map(part => parseInt(part).toString(2).padStart(8, '0')).join('.');
    const maskBinary = mask.split('.').map(part => parseInt(part).toString(2).padStart(8, '0')).join('.');
    if(!isValidIP(ipBinary) || !isValidMask(maskBinary)) return '非法地址或掩码';
    
    if(isInRange(ipBinary, '1.0.0.0','126.255.255.255')){
        return 'A类地址';
    }else if(isInRange(ipBinary, '128.0.0.0','191.255.255.255')){
        return 'B类地址';
    }else if(isInRange(ipBinary, '192.0.0.0','223.255.255.255')){
        return 'C类地址';
    }else if(isInRange(ipBinary, '224.0.0.0','239.255.255.255')){
        return 'D类地址';
    }else if(isInRange(ipBinary, '240.0.0.0','255.255.255.255')){
        return 'E类地址';
    }else if(isInRange(ipBinary, '10.0.0.0','10.255.255.255') ||
             isInRange(ipBinary, '172.16.0.0','172.31.255.255') ||
             isInRange(ipBinary, '192.168.0.0','192.168.255.255')){
        return '私网地址';
    }else {
        return '非法地址';
    }
}
// 判断IP地址是否合法
function isValidIP(ipBinary) {
  const parts = ipBinary.split('.');
  return parts.length === 4 && parts.every(part => part.length === 8 && parseInt(part, 2) >= 0 && parseInt(part, 2) <= 255);
}
// 判断掩码是否合法
function isValidMask(maskBinary) {
  const onesIndex = maskBinary.indexOf('0');
  const zerosIndex = maskBinary.indexOf('1');
  return onesIndex !== -1 && zerosIndex !== -1 && onesIndex < zerosIndex;
}

// 判断IP地址是否在指定范围内
function isInRange(ipBinary, start, end) {
  const startBinary = start.split('.').map(part => parseInt(part).toString(2).padStart(8, '0')).join('.');
  const endBinary = end.split('.').map(part => parseInt(part).toString(2).padStart(8, '0')).join('.');
  return ipBinary >= startBinary && ipBinary <= endBinary;
}