【华为OJ18】识别有效的IP地址和掩码并进行分类统计

该博客主要介绍如何解析并分类IP地址及其掩码,包括A、B、C、D、E五类地址的范围定义,同时涵盖私网IP地址的识别。读者将学习到如何对有效的IP地址进行正确归类。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述

请解析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就是一个非法的掩码)
本题暂时默认以0开头的IP地址是合法的,比如0.1.1.2,是合法地址

输入描述:

多行字符串。每行一个IP地址和掩码,用~隔开。

输出描述:

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

输入例子:
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
import java.math.BigInteger;
import java.util.Scanner;
/**
 * 题目描述
	请解析IP地址和对应的掩码,进行分类识别。要求按照A/B/C/D/E类地址归类,不合法的地址和掩码单独归类。
	所有的IP地址划分为 A,B,C,D,E五类
 * @author WGS
 */
public class Main{

	private static int a =0;
	private static int b =0;
	private static int c =0;
	private static int d =0;
	private static int e =0;
	private static int errors =0;
	private static int privateIP =0;
	
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		while(sc.hasNext()){
			String str=sc.next();
			checkIp(str);
		}
		System.out.println(a+" "+b+" "+c+" "+d+" "+e+" "+errors+" "+privateIP);
		sc.close();
	}

	private static void checkIp(String str) {//str:10.70.44.68~255.254.255.0
		String[] s=str.split("~");
		
		String[] ipStr=s[0].split("\\.");//获得IP:  10/70/44/68
		String[] maskStr=s[1].split("\\.");//获得掩码:255.254.255.0
		
		//****1 注意!!!错误IP地址或错误掩码的判断一定要放在最前面判断,因为判断出了是错误IP地址或错误掩码后
		//就直接return,不用判断是不是后面的ABCDE类或者私有IP  *****
        
		//1-1 错误IP
		if(ipStr.length!=4 || maskStr.length!=4){
			errors++;//错误IP
			return;
		}
        // 判断IP中的每一部分格式
		for (int i = 0; i < 4; i++) {
	        if (" ".equals(ipStr[i]) ||  " ".equals(maskStr[i])) {
	           	 errors++;
	           	 return;
	        }
	     }
		 
        int[] ipInts = new int[4];
        int[] maskInts = new int[4];
         // 将IP解析成数字
        for (int i = 0; i < 4; i++) {
            ipInts[i] = Integer.parseInt(ipStr[i]);
            maskInts[i] = Integer.parseInt(maskStr[i]);
            if (ipInts[i] > 255 || maskInts[i] > 255) {
                errors++;
                return;
            }
        }
		//1-2   错误掩码:255.255.255.32  必须是前面全为1,后面全为0,即从后往前至少有一位是0,且0前的数字全为1
			//即首先得到第一个0的位置,再判断0后是否有1,有即为错误掩码
		 
		 //将掩码转为为二进制:好判断0,1位置
        String tempStr = "";
        //例如将255.254.255.0转换成二进制:
        //255:1111 1111
        //254:1111 1110
        //255:1111 1111
        //	0:0
        for(int i = 0; i<maskInts.length; i++){
            String str2 = Integer.toBinaryString( maskInts[i] );
            //判断一下:如果转化为二进制为0或者1或者不满8位,要在数后补0
            int bit = 8-str2.length();
            if(str2.length()<8){
                for(int j=0; j<bit; j++){
                	str2 = "0"+str2;
                }
            }
            tempStr += str2;
        }
        
		int indexOfFirstZero = tempStr.indexOf("0");
        tempStr = tempStr.substring(indexOfFirstZero + 1);

		if(tempStr.contains("1")){
			errors++;
         	return;
		}
			
		//获得IP地址第一部分数字 
		int ipFirstPart=Integer.parseInt(ipStr[0]);
		int ipSecondPart = Integer.parseInt(ipStr[1]);
        
		
		//3  判断ABCDE 类IP 地址
		if(ipFirstPart>= 1 && ipFirstPart <= 126 ){
			a++;
			//2 判断私有IP个数,私有IP和ABCDE 类IP地址判断不冲突,即IP是私有IP一类,也可以是ABCDE一类
			if(ipFirstPart == 10){
				privateIP++;
			}
		}
		if(ipFirstPart>= 128 && ipFirstPart <= 191 ){
			b++;
			//2 判断私有IP个数
			if(ipFirstPart == 172){
				if(ipSecondPart >= 16 && ipSecondPart<= 31){
					privateIP++;
				}
			}
		}
		if(ipFirstPart>= 192 && ipFirstPart <= 223 ){
			c++;
			//2 判断私有IP个数
			if(ipFirstPart==192){
				if(ipSecondPart == 168){
					privateIP++;
				}
			}
		}
		if(ipFirstPart>= 224 && ipFirstPart <= 239 ){
			d++;
		}
		if(ipFirstPart>= 240 && ipFirstPart <= 255 ){
			e++;
		}
        
	}

}








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值