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

该博客主要讨论如何解析和分类IP地址及其掩码,包括A、B、C、D、E类地址的识别,私有IP的判断,以及错误IP和掩码的处理。通过示例代码展示了如何处理输入的IP地址和掩码,统计各类地址的数量。

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

识别有效的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的个数,之间以空格隔开。

示例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.68255.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
输入:
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地址,计数时请忽略

题目里面陷阱很多,需要搞清楚。

暴力法:

#include <iostream>
#include <string>
using namespace::std;

typedef struct {
    int32_t first;
    int32_t second;
    int32_t third;
    int32_t fourth;
}IP_int;

typedef struct {
    int ANumber;
    int BNumber;
    int CNumber;
    int DNumber;
    int ENumber;
    int errIPNumber;
    int priIPNumber;
}res_t;

static int processInput(string s, IP_int *IP, IP_int *mask) {
    int flage = 0;
    for (int i = 0 ; i < s.length(); ) {
        if (!flage) {
            string first;
            while (i < s.length() && s[i]!='.' && s[i]!='~') {
                first += s[i];
                i++;
            }
            if(first!="") IP->first = stoi(first);
            i++;
            if (i < s.length() && s[i]=='~') { flage = 1; i++; continue; };
            string second;
            while (i < s.length() && s[i]!='.' && s[i]!='~') {
                second += s[i];
                i++;
            }
            if(second!="") IP->second = stoi(second);
            if (i < s.length() && s[i]=='~') { flage = 1; i++; continue; };
            i++;
            
            string third;
            while (i < s.length() && s[i]!='.' && s[i]!='~') {
                third += s[i];
                i++;
            }
            if(third!="") IP->third = stoi(third);
            if (i < s.length() && s[i]=='~') { flage = 1; i++; continue; };
            i++;
            
            string fourth;
            while (i < s.length() && s[i]!='.' && s[i]!='~') {
                fourth += s[i];
                i++;
            }
            if(fourth!="") IP->fourth = stoi(fourth);
            if (i < s.length() && s[i]=='~') { flage = 1; i++; continue; };
            i++;
        } else {
			string first;
			while (i < s.length() && s[i] != '.' && s[i] != '\0') {
				first += s[i];
				i++;
			}
			if(first!="") mask->first = stoi(first);
			if (i < s.length() && s[i] == '\0') break;
			i++;
			string second;
			while (i < s.length() && s[i] != '.' && s[i] != '\0') {
				second += s[i];
				i++;
			}
			if(second!="") mask->second = stoi(second);
			if (i < s.length() && s[i] == '\0') break;
			i++;

			string third;
			while (i < s.length() && s[i] != '.' && s[i] != '\0') {
				third += s[i];
				i++;
			}
			if(third!="") mask->third = stoi(third);
			if (i < s.length() && s[i] == '\0') break;
			i++;
			string fourth;
			while (i < s.length() && s[i] != '.' && s[i] != '\0') {
				fourth += s[i];
				i++;
			}
			if(fourth!="") mask->fourth = stoi(fourth);
			if (i < s.length() && s[i] == '\0') break;
			i++;
        }
        if (i < s.length() && s[i]=='~') flage = 1;
        i++;
    }
    return 0;
}
#define CAL_ERR (0)
#define MASK_RIGHT (1)
#define CAL_RIGHT MASK_RIGHT

void dec2binary(int num, uint8_t *mask_binary)
{
    int t = num;
    for(int i=0; i<8; i++)
    {
        mask_binary[i] = t & 1;
        t = t>>1;
    }
}

static int cal_Mask(IP_int *mask_input) {
    if (mask_input->first < 0 || mask_input->first > 255) return CAL_ERR;
    if (mask_input->second < 0 || mask_input->second > 255) return CAL_ERR;
    if (mask_input->third < 0 || mask_input->third > 255) return CAL_ERR;
    if (mask_input->fourth < 0 || mask_input->fourth > 255) return CAL_ERR;
    uint8_t s[32] = {0};
    int index = 31;
    uint8_t mask_binary[8] = {0};
    dec2binary(mask_input->first, mask_binary);
    for (int i = 7; i >= 0; i--) {
        s[index--] = mask_binary[i];
    }
    dec2binary(mask_input->second, mask_binary);
    for (int i = 7; i >= 0; i--) {
        s[index--] = mask_binary[i];
    }
    dec2binary(mask_input->third, mask_binary);
    for (int i = 7; i >= 0; i--) {
        s[index--] = mask_binary[i];
    }
    dec2binary(mask_input->fourth, mask_binary);
    for (int i = 7; i >= 0; i--) {
        s[index--] = mask_binary[i];
    }

    int left = 31;
    int right = 0;
    while (left >= 0 && s[left] == 1) left--;
    while (right < 32 && s[right] == 0) right++;
    if (left < 0 || right > 31) return CAL_ERR;
    if ((left < right)) {
        return MASK_RIGHT;
    }
//     if (left > right){
//         return CAL_ERR;
//     }
//     if (left == right){
//         return MASK_RIGHT;
//     }
    return CAL_ERR;
    
}
static int IP_il(IP_int *IP_input){
    if (IP_input->first < 0 || IP_input->first > 255 ) {
        //res->errIPNumber++;
        return CAL_ERR;
    }
    if (IP_input->second < 0 || IP_input->second > 255) {
        //res->errIPNumber++;
        return CAL_ERR;
    }
    if (IP_input->third < 0 || IP_input->third > 255) {
        //res->errIPNumber++;
        return CAL_ERR;
    }
    if (IP_input->fourth < 0 || IP_input->fourth > 255) {
        //res->errIPNumber++;
        return CAL_ERR;
    }
    return CAL_RIGHT;
}

static int cal_IP(IP_int *IP_input, res_t *res, int pre) {
    
    if ((IP_input->first >= 1) && (IP_input->first <= 126)) {
        if (pre == MASK_RIGHT) res->ANumber++;
        if (IP_input->first == 10) res->priIPNumber++;
        return CAL_RIGHT;
    }
    else if ((IP_input->first >= 128) && (IP_input->first <= 191)) {
        if (pre == MASK_RIGHT) res->BNumber++;
        if ( IP_input->first == 172 && IP_input->second >= 16 && IP_input->second <= 31) res->priIPNumber++;
        return CAL_RIGHT;
    }
    else if ((IP_input->first >= 192) && (IP_input->first <= 223)) {
        if (pre == MASK_RIGHT) res->CNumber++;
        if (IP_input->first == 192 && IP_input->second == 168) res->priIPNumber++;
        return CAL_RIGHT;
    }
    else if ((IP_input->first >= 224) && (IP_input->first <= 239)) {
        if(pre == MASK_RIGHT) res->DNumber++;
        return CAL_RIGHT;
    }
    else if ((IP_input->first >= 240) && (IP_input->first <= 255)) {
        if(pre == MASK_RIGHT) res->ENumber++;
        return CAL_RIGHT;
    }
    //if(pre == MASK_RIGHT) res->errIPNumber++;    
    return CAL_RIGHT;
}



static void cal_number(IP_int *IP_input, IP_int *mask_input, res_t *res) {
    int t = cal_Mask(mask_input);
//     if (t == 0) res->errIPNumber++;
    if (IP_input->first == 127) return;//|| mask_input->fourth == 0xffffffff
    int ti = IP_il(IP_input);
    if (ti == CAL_ERR && t == CAL_ERR) return;
    if (ti == CAL_ERR || t == CAL_ERR) {
        res->errIPNumber++;
        return;
    }
    if (ti == CAL_RIGHT && t == CAL_RIGHT) cal_IP(IP_input,res,t);

    return ;
}

int main(){
    string input;
    res_t res = {0};
    
    while(cin>>input){
        IP_int IP = {256,256,256,256};
        IP_int mask = {256,256,256,256};
        processInput(input, &IP, &mask);
//         cout<<IP.first<<" "<<IP.second<<" "<<IP.third<<" "<<IP.fourth<<endl;
//         cout<<mask.first<<" "<<mask.second<<" "<<mask.third<<" "<<mask.fourth<<endl;
        cal_number(&IP, &mask, &res);
    }
    cout<<res.ANumber<<" "<<res.BNumber<<" "<<res.CNumber<<" "<<res.DNumber<<" "<<res.ENumber
        <<" "<<res.errIPNumber<<" "<<res.priIPNumber<<endl;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值