华为机试-018-较难-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类地址是不冲突的

1.1、输入描述

多行字符串。每行一个IP地址和掩码,用~隔开。
请参考帖子https://www.nowcoder.com/discuss/276处理循环输入的问题。

1.2、输出描述

  • 统计A、B、C、D、E、错误IP地址或错误掩码、私有IP的个数,之间以空格隔开。

二、示例

2.1、示例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

说明:

10.70.44.68~255.254.255.0的子网掩码非法,
19..0.~255.255.255.0的IP地址非法,所以错误IP地址或错误掩码的计数为2;
1.0.0.1~255.0.0.0是无误的A类地址;
192.168.0.2~255.255.255.0是无误的C类地址且是私有IP;
所以最终的结果为1 0 1 0 0 2 1

2.2、示例2

输入:

0.201.56.50~255.255.111.255
127.201.56.50~255.255.111.255

输出:

0 0 0 0 0 0 0

说明:

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

三、答案(java)

3.1、方法一

结合几位大佬的题解,整出一个Java版.这里有个大坑,若是ip是0或者127开头的直接忽略,即使子网掩码是非法的,也不能将此算到error里去。 具体实现

1、查看ip第一段是否为“0”或“127”,若是忽略;

2、判断子网掩码是否合法,如果满足下列条件之一即为非法掩码

  • 数字段数不为4
  • 在二进制下,不满足前面连续是1,然后全是0
  • 在二进制下,全为0或全为1

3、判断IP地址是否合法,如果满足下列条件之一即为非法地址

  • 数字段数不为4,比如存在空段,即【192…1.0】这种;
  • 某个段的数字大于255

4、判断ip是否是ABCDE类地址,若是对应类加一。 所有的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

5、判断ip是否私有地址。 私网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

package com.tzq.hwod;

import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int aNum = 0;
		int bNum = 0;
		int cNum = 0;
		int dNum = 0;
		int eNum = 0;
		int errNum = 0;
		int pNum = 0;
		while (sc.hasNextLine()) {
			String str = sc.nextLine();
			if (str.equals("exit")) {
				break;
			}
			String[] strArr = str.split("~");
			int ipFirst = getIpSeg(strArr[0], 0);
			if (ipFirst == 0 || ipFirst == 127) {
				continue;
			}
			if (maskIsInvaild(strArr[1])) {
				errNum++;
				continue;
			}
			if (ipIsInvaild(strArr[0])) {
				errNum++;
				continue;
			}
			if (ipFirst >= 1 && ipFirst <= 126) {
				aNum++;
			}
			if (ipFirst >= 128 && ipFirst <= 191) {
				bNum++;
			}
			if (ipFirst >= 192 && ipFirst <= 223) {
				cNum++;
			}
			if (ipFirst >= 224 && ipFirst <= 239) {
				dNum++;
			}
			if (ipFirst >= 240 && ipFirst <= 255) {
				eNum++;
			}
			int ipSecond = getIpSeg(strArr[0], 1);
			if (ipFirst == 10 || (ipFirst == 172 && ipSecond >= 16 && ipSecond <= 31)
					|| (ipFirst == 192 && ipSecond == 168)) {
				pNum++;
			}
		}
		System.out.println(aNum + " " + bNum + " " + cNum + " " + dNum + " " + eNum + " " + errNum + " " + pNum);
	}

	public static boolean maskIsInvaild(String mask) {
		String[] maskArr = mask.split("\\.");
		if (maskArr.length != 4) {
			return true;
		}
		String maskBinary = toBinary(maskArr[0]) + toBinary(maskArr[1]) + toBinary(maskArr[2]) + toBinary(maskArr[3]);
		if (!maskBinary.matches("[1]{1,}[0]{1,}")) {
			return true;
		}
		return false;
	}

	public static String toBinary(String num) {
		String numBinary = Integer.toBinaryString(Integer.valueOf(num));
		while (numBinary.length() < 8) {
			numBinary = "0" + numBinary;
		}
		return numBinary;
	}

	public static boolean ipIsInvaild(String ip) {
		String[] ipArr = ip.split("\\.");
		if (ipArr.length != 4) {
			return true;
		}
		if (Integer.valueOf(ipArr[0]) > 255 || Integer.valueOf(ipArr[1]) > 255 || Integer.valueOf(ipArr[2]) > 255
				|| Integer.valueOf(ipArr[3]) > 255) {
			return true;
		}
		return false;
	}

	public static int getIpSeg(String ip, int index) {
		String[] ipArr = ip.split("\\.");
		return Integer.valueOf(ipArr[index]);
	}
}

在这里插入图片描述

四、答案(python 3)

4.1、方法一

#!/usr/bin/python
# -*- coding: UTF-8 -*-

ipClass2num = {
    'A':0,
    'B':0,
    'C':0,
    'D':0,
    'E':0,
    'ERROR':0,
    'PRIVATE':0,
}
# 私有IP地址和A,B,C,D,E类地址是不冲突的,也就是说需要同时+1
def check_ip(ip:str):
    ip_bit = ip.split('.')
    if len(ip_bit) != 4 or '' in ip_bit:  #ip 的长度为4 且每一位不为空
        return False
    for i in ip_bit:
        if int(i)<0 or int(i) >255:   #检查Ip每一个10位的值范围为0~255
            return False
    return True
def check_mask(mask:str):
    if not check_ip(mask):
        return False
    if mask == '255.255.255.255' or mask == '0.0.0.0':
        return False
    mask_list = mask.split('.')
    if len(mask_list) != 4:
        return False
    mask_bit = []
    for i in mask_list:#小数点隔开的每一数字段
        i = bin(int(i))#每一数字段转换为每一段的二进制数字段
        i = i[2:] #从每一段的二进制数字段的第三个数开始,因为前面有两个ob
        mask_bit.append(i.zfill(8)) #.zfill:返回指定长度的字符串,原字符串右对齐,前面填充0
    whole_mask = ''.join(mask_bit)
#     print(whole_mask)
    whole0_find = whole_mask.find("0")#查0从哪里开始
    whole1_rfind = whole_mask.rfind("1")#查1在哪里结束
    if whole1_rfind+1 == whole0_find:#两者位置差1位为正确
        return True
    else:
        return False
def check_private_ip(ip:str):
    # 三类私网
    ip_list = ip.split('.')
    if ip_list[0] == '10': return True
    if ip_list[0] == '172' and 16<=int(ip_list[1])<=31: return True
    if ip_list[0] == '192' and ip_list[1] == '168': return True
    return False
while True:
    try:
        s = input()
        ip = s.split('~')[0]
        mask = s.split('~')[1]
        if check_ip(ip):
            first = int(ip.split('.')[0])
            if first==127 or first==0:
                # 若不这样写,当类似于【0.*.*.*】和【127.*.*.*】的IP地址的子网掩码错误时,会额外计数
                continue
            if check_mask(mask):
                if check_private_ip(ip):
                    ipClass2num['PRIVATE'] += 1
                if 0<first<127:
                    ipClass2num['A'] += 1
                elif 127<first<=191:
                    ipClass2num['B'] += 1
                elif 192<=first<=223:
                    ipClass2num['C'] += 1
                elif 224<=first<=239:
                    ipClass2num['D'] += 1
                elif 240<=first<=255:
                    ipClass2num['E'] += 1
            else:
                ipClass2num['ERROR'] += 1
        else:
            ipClass2num['ERROR'] += 1
    except:
        break
for v in ipClass2num.values():
    print(v,end=(' '))

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Tzq@2018

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值