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类地址是不冲突的

输入描述:

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

请参考帖子https://www.nowcoder.com/discuss/276处理循环输入的问题。

输出描述:

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

注意

本题目需要先排除0.*.*.*和127.*.*.*.的情况,然后判断IP和掩码是不是合法,在IP和掩码都合法的情况下,才能对IP地址分类,在IP地址分类的时候顺便确认是不是私有IP地址。

注意

如果ip地址和掩码都错误的情况下,错误数应该加2!

判断IP地址是否合法

  1. 只有0123456789.~这些字符
  2. 有’~'这个符号
  3. 最后没有’.'这个符号
  4. 每个’.'之间的数字大于等于0或者小于等于255

判断掩码是否合法

  1. 0.0.0.0和255.255.255.255不合法
  2. 掩码分成四段,如果后面的大于前面的那么肯定就不合法了
  3. 每一段前面全1后面全零的情况可以按下列方法列出(这里已经排除全0和全1的情况了)
  4. 如果每一段都合法,那么掩码合法
if(mmask[i]==255||mmask[i] == 254 || mmask[i] == 252 || mmask[i] == 248 ||mmask[i] == 240 || mmask[i] == 224 || mmask[i]== 191 || mmask[i] == 128||mmask[i]==0) 

代码

#include<iostream>
#include<cstring>
#include<vector>
#include<cctype>
#include<string.h>
using namespace std;
int Acount = 0;
int Bcount = 0;
int Ccount = 0;
int Dcount = 0;
int Ecount = 0;
int errorCount = 0;
int privateCount = 0;
vector<string>ip;
vector<string>mask;

//判断字符串是否合法
bool isValidStr(string str) {
    if (str == "") return false;
    if (stoi(str) < 0 || stoi(str) > 255) return false;
    return true;
}
//判断IP地址是否合法
bool isValidIp(vector<string>& ip) {

    for (auto i : ip) {
        if (isValidStr(i) == false) return false;

    }
    return true;
}


//判断掩码是否合法
bool isValidMask(vector<string>&mask) {
   int mmask[4];
    int k=0;
    for(auto s:mask){
        if(s=="") return false;
        mmask[k]=stoi(s);
        //cout<<mmask[k];
        k++;

    }
    if(mmask[0]==0||mmask[3]==255) return false;
    for(int i=1;i<4;i++){
        if(mmask[i]>mmask[i-1]) return false;

    }
    int truenum=0;
    for(int i=0;i<4;i++){
 
        if(mmask[i]==255||mmask[i] == 254 || mmask[i] == 252 || mmask[i] == 248 ||mmask[i] == 240 || mmask[i] == 224 || mmask[i]== 191 || mmask[i] == 128||mmask[i]==0) truenum++;
    }
    if(truenum==4) return true;
    return false;


}
//给合法的IP地址分类
void ipClass(vector<string>& ip) {
    int num = stoi(ip[0]);
    if (num >= 1 && num <= 126) {
        Acount++;
        if (stoi(ip[0]) == 10 && stoi(ip[1]) >= 0 && stoi(ip[1]) <= 255) privateCount++;
    } else if (num >= 128 && num <= 191) {
        Bcount++;
        if (stoi(ip[0]) == 172 && stoi(ip[1]) >= 16 &&
                stoi(ip[1]) <= 31) privateCount++;
    } else if (num >= 192 && num <= 223) {
        Ccount++;
        if (stoi(ip[0]) == 192 && stoi(ip[1]) == 168 && stoi(ip[2]) >= 0 &&
                stoi(ip[2]) <= 255) privateCount++;
    } else if (num >= 224 && num <= 239) Dcount++;
    else if (num >= 240 && num <= 255) Ecount++;
}

int main() {
    string str;
    while (getline(cin, str)) {
        if(str.find_first_not_of("0123456789.~")!=string::npos) {
            errorCount++;
            continue;
        }
        
    if(str.find("~")==string::npos) {
        errorCount++;
        continue;
    }
        
    if(str.rfind(".")==str.size()-1)  {
        errorCount++;
        continue;
    }
       
        ip.clear();
        mask.clear();
     
        int start = 0;
        int index = 0;
        //处理IP地址输入
        str += ".";
        for (; index < str.size(); index++) {
            if (str[index] == '.') {
                string tmp = str.substr(start, index - start + 1);
                tmp.pop_back();
                start = index + 1;
                ip.push_back(tmp);
            }
            if (str[index] == '~') {
                string tmp = str.substr(start, index - start + 1);
                tmp.pop_back();
                start = index + 1;
                ip.push_back(tmp);
                break;
            }
        }

        //处理掩码输入
        for (; index < str.size(); index++) {
            if (str[index] == '.') {
                string tmp = str.substr(start, index - start + 1);
                tmp.pop_back();
                start = index + 1;
                mask.push_back(tmp);
            }
        }

        //忽略特殊情况
        if (ip[0] == "0" || ip[0] == "127") continue;
        //判断是不是合法IP或者掩码

        if(!isValidIp(ip)) errorCount++;
        if(!isValidMask(mask)) errorCount++;

        if(isValidIp(ip)&&isValidMask(mask)){
            ipClass(ip);
        }

    }
    cout << Acount << " " << Bcount << " " << Ccount << " " << Dcount << " " <<
         Ecount << " " << errorCount << " " << privateCount << endl;

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值