识别有效的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

输入

多行字符串。每行一个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

输出

统计A、B、C、D、E、错误IP地址或错误掩码、私有IP的个数,之间以空格隔开,根据上面的IP,可以得到:

1.0.0.1~255.0.0.0 —-A类

192.168.0.2~255.255.255.0 —-C类,私有

10.70.44.68~255.254.255.0—-错误的掩码

19..0.~255.255.255.0—–错误的IP

可以得到统计数据如下:

1 0 1 0 0 2 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

思路

字符串的截取

while(i<ip1.size())
        {
            int tmp=i;
            while(isdigit(ip1[tmp]))
                tmp++;
            str1[k]=ip1.substr(i,tmp-i);
            k++;
            i=tmp+1;
        }
string Chang(string str)    //转换为二进制
{
    int num=atoi(str.c_str());
    string tmp;
    char tmp1[10]={0};
    itoa(num,tmp1,2);
    tmp=string(tmp1);
    if (tmp.size()<8)
    {
        string tmp2(8-tmp.size(),'0');//创建临时字符串填充到前面
        str=tmp2+tmp;
    }
    else
        str=tmp;
    return str;
}

代码

#include <iostream>
#include <string>
#include <vector>
using namespace std;
static int result[7]= {0};  //保存最后结果的数组
string Chang(string str)    //转换为二进制
{
    int num=atoi(str.c_str());
    string tmp;
    char tmp1[10]= {0};
    itoa(num,tmp1,2);
    tmp=string(tmp1);
    if (tmp.size()<8)
    {
        string tmp2(8-tmp.size(),'0');//创建临时字符串填充到前面
        str=tmp2+tmp;
    }
    else
        str=tmp;
    return str;
}
void checkNetSegment(string mask,string ip1)
{

    int count1=0;//掩码的点个数(不连续的点等于3个)
    int count2=0;//ip1的点个数
    int count4=0;//掩码的点个数(所有的点等于3个)
    int count5=0;//ip1的点个数
    string str1[4],str3[4];
    for(int i=0; i<mask.size(); i++)
    {
        if(mask[i]=='.' && mask[i+1]!='.')
        {
            count1++;//掩码的点个数(不连续的点等于3个)
        }
        if(mask[i]=='.')
            count4++;//掩码的点个数(所有的点等于3个)
    }

    for(int i=0; i<ip1.size(); i++)
    {
        if(ip1[i]=='.' && ip1[i+1]!='.')
        {
            count2++;//ip1的点个数(不连续的点等于3个)
        }
        if(ip1[i]=='.')
        {
            count5++;//ip1的点个数(所有的点等于3个)
        }
    }

    //利用对点的个数判断是否格式正确
    if(count1==count2&&count1==3
            && count4==count5&&count4==3)  //如果格式正确
    {
        int i=0;                         //ip1先分解为4段
        int flag1=0;
        int k=0;
        while(i<ip1.size())
        {
            int tmp=i;
            while(isdigit(ip1[tmp]))
                tmp++;
            str1[k]=ip1.substr(i,tmp-i);
            k++;
            i=tmp+1;
        }
        i=0;                   //掩码分为4段
        int flag3=0,flagmk=0;
        k=0;
        string test;
        while(i<mask.size())
        {
            int tmp=i;
            while(isdigit(mask[tmp]))
                tmp++;
            str3[k]=mask.substr(i,tmp-i);
            k++;
            i=tmp+1;
        }
        for(int i=0; i<4; i++)
        {
            //判断每一段的值是否在0-255之间
            if(atoi(str1[i].c_str())<256 &&atoi(str1[i].c_str())>=0)
            {
                flag1++;//IP
            }
        }

        for(int i=0; i<4; i++)
        {
            if(atoi(str3[i].c_str())<256 &&atoi(str3[i].c_str())>=0)
            {
                flag3++;//MASK
            }
        }

        for (int i=0; i<4; i++)      //判掩码是不是1在0前面
        {
            string temp=Chang(str3[i]);
            test+=temp;
        }

        for (int j=1; j<32-1; j++)
        {
            if (test[j-1]>test[j] && test[j]<test[j+1])
            {
                flagmk=1;
                break;
            }
        }

        if(flag1==flag3 &&flag3==4 &&flagmk==0)      //格式正确
        {

            if (str1[0]>="1" &&str1[0]<="126" )
            {
                result[0]++;
            }
            else if (str1[0]>="128" &&str1[0]<="191")
            {
                result[1]++;
            }
            else if (str1[0]>="192"&&str1[0]<="223")
            {
                result[2]++;
            }
            else if (str1[0]>="224"&&str1[0]<="239")
            {
                result[3]++;
            }
            else if (str1[0]>="240"&&str1[0]<="255")
            {
                result[4]++;
            }
            else if (str1[0]=="127")
            {
                result[5]++;
            }

            if (str1[0]=="10"||         //私有IP
                    (str1[0]=="172"&&str1[1]>="16"&&str1[1]<="31")||
                    (str1[0]=="192"&&str1[1]=="168"))
            {
                result[6]++;
            }

        }
        else
        {
            result[5]++;
        }
    }
    else
    {
        result[5]++; //格式不正确
    }

}
int main()
{
    string s1,ms,ip;
    while (getline(cin,s1))
    {
        //截取字符串
        int position=s1.find("~",0);
        ip=s1.substr(0,position);
        ms=s1.substr(position+1,s1.size()-1);
        checkNetSegment(ms,ip);
    }
    for (int i=0; i<7; i++)
    {
        cout<<result[i];
        if (i==6)
        {
            cout<<endl;
        }
        else
        {
            cout<<" ";
        }
    }
    return 0;
}

这里写图片描述

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

另外:网上搜罗来的代码

来自:

#include <iostream>
#include <string>
#include <cstring>
#include <vector>
#include <cstdio>
using namespace std;
bool checkip(vector<int> num)
{
    for (int i = 0; i < 4; i++)
    {
        if (num[i] < 0 || num[i] > 255)
        {
            return false;
        }
    }
    return true;
}
bool checkmark(vector<int> num)
{
    int sum = num[0] << 24 | num[1] << 16 | num[2] << 8 | num[3];
    bool b = false;
    for (int i = 0; i < 32; i++)
    {
        if ((sum & 1 << i) == 0)
        {
            if (b == true)
            {
                return false;
            }
        }
        else
        {
            b = true;
        }
    }
    return true;
}
int str2num(string str)
{
    int res = 0;
    for (int i = 0; i < str.size(); i++)
    {
        res = res * 10 + str[i] - '0';
    }
    return res;
}
vector<int> seperate(string str)
{
    vector<int> ss;
    int i = 0;
    int j;
    string temp;
    while ((j = str.find('.', i)) != string::npos)
    {
        temp = str.substr(i, j - i);
        if (temp.size() != 0)
        {
            ss.push_back(str2num(temp));
        }
        else
        {
            ss.push_back(-1);
        }
        i = j + 1;
    }
    temp = str.substr(i);
    if (temp.size() != 0)
    {
        ss.push_back(str2num(temp));
    }
    else
    {
        ss.push_back(-1);
    }
    return ss;
}
int main()
{
    string str;
    int cnt[7] = {0};
    while (getline(cin, str))
    {
        if (str.size() == 0)
        {
            break;
        }
        int i = 0;
        int j;
        j = str.find('~');
        string strIp = str.substr(0, j);
        string strMark = str.substr(j + 1);
        vector<int> ip = seperate(strIp);
        vector<int> mark = seperate(strMark);
        if (checkip(ip) && checkmark(mark))
        {
            if (ip[0] >= 1 && ip[0] <= 126)
            {
                cnt[0]++;
            }
            else if (ip[0] >= 128 && ip[0] <= 191)
            {
                cnt[1]++;
            }
            else if (ip[0] >= 192 && ip[0] <= 223)
            {
                cnt[2]++;
            }
            else if (ip[0] >= 224 && ip[0] <= 239)
            {
                cnt[3]++;
            }
            else
            {
                cnt[4]++;
            }
            if ((ip[0] == 10) || (ip[0] == 172 && ip[1] >= 16 && ip[1] <= 31)
                || (ip[0] == 192 && ip[1] == 168))
            {
                cnt[6]++;
            }
        }
        else
        {
            cnt[5]++;
        }
    }
    for (int i = 0; i < 7; i++)
    {
        cout<<cnt[i]<<" ";
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值