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

来源:互联网 发布:stm32单片机项目大全 编辑:程序博客网 时间:2024/06/10 00:02

题目
请解析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地址和掩码,用~隔开。
输出描述:
统计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

解决思路:
1、将IP地址和掩码地址转换成整数进行判断。
2、先判断掩码是否有效,再判断IP地址是否有效,都满足就进行分类统计。
(这里有一个问题,子网掩码的范围没有判断???)

#include <iostream>#include <vector>#include <string>using namespace std;/*记录IP地址和掩码*/typedef struct {    string ip;    string mask;}IP;/*统计信息结构体*/typedef struct {    int AIpCount;    int BIpCount;    int CIpCount;    int DIpCount;    int EIpCount;    int ErrIpOrMaskCount;    int PrivateIpCount;}Statistics;/*将地址的转换成int类型,并记录到数组num中*/int addrStringToInt(string addr, vector<int> &num) {    int i, j, len = addr.size();    string tmp;    for (i = 0, j = 0; i < len; i++) {        if (addr[i] == '.') {            tmp = addr.substr(j, i - j);            j = i + 1;            //处理非法的地址            if (tmp.empty()) {                return -1;            }            num.push_back(atoi(tmp.c_str()));        }    }    tmp = addr.substr(j, i - j);    if (tmp.empty()) {        return -1;    }    num.push_back(atoi(tmp.c_str()));    //保证地址由4个整数组成    if (num.size() != 4) {        return -1;    }    return 0;}void checkIpAddr(string ip, Statistics &sta) {    vector<int> numOfIp;    if (addrStringToInt(ip, numOfIp) == -1) {        sta.ErrIpOrMaskCount++;        return;    }    /*    A~E类地址后三个整数均要满足位于[0,255]闭区间    */    if (numOfIp[1] < 0 || numOfIp[1]>255 || numOfIp[2] < 0 || numOfIp[2] > 255 ||        numOfIp[3] < 0 || numOfIp[3] > 255) {        sta.ErrIpOrMaskCount++;        return;    }    //A类地址    if (numOfIp[0] > 0 && numOfIp[0] < 127) {        sta.AIpCount++;        //私网IP        if (numOfIp[0] == 10) {            sta.PrivateIpCount++;        }    }//B类地址    else if (numOfIp[0] > 127 && numOfIp[0] <= 191) {        sta.BIpCount++;        //私网IP        if (numOfIp[0] == 172 && numOfIp[1] >= 16 && numOfIp[1] <= 31) {            sta.PrivateIpCount++;        }    }//C类地址    else if (numOfIp[0] > 191 && numOfIp[0] <= 223) {        sta.CIpCount++;        //私网IP        if (numOfIp[0] == 192 && numOfIp[1] == 168) {            sta.PrivateIpCount++;        }    }//D类地址    else if (numOfIp[0] > 223 && numOfIp[0] <= 239) {        sta.DIpCount++;    }//E类地址    else if (numOfIp[0] > 239 && numOfIp[0] <= 255) {        sta.EIpCount++;    }//非法地址    else {        sta.ErrIpOrMaskCount++;    }    return;}int validMaskAddr(string mask) {    vector<int> numOfMask;    int i, j;    if (addrStringToInt(mask, numOfMask) == -1) {        return -1;    }    /*    掩码转换成IP地址后,要满足位于[0,255]闭区间    */    if (numOfMask[0] < 0 || numOfMask[0] > 255 ||         numOfMask[1] < 0 || numOfMask[1] > 255 ||         numOfMask[2] < 0 || numOfMask[2] > 255 ||        numOfMask[3] < 0 || numOfMask[3] > 255) {        return -1;    }    /*    掩码地址出现比特0后,保证后续的比特均为0。如果全为255,则直接通过。如果出现0<num<255的数,则判断(num-1)|num == 0xff。如果出现0,则判断是否接下来的数都是0。    */    for (i = 0; i < 4; i++) {        if(numOfMask[i] < 255){            if (numOfMask[i] > 0 && ((numOfMask[i] - 1) | numOfMask[i]) != 0xFF) {                return -1;            }            break;        }    }    for (j = i+1; j < 4; j++) {        if (numOfMask[j] != 0) {            return -1;        }    }    return 0;}void getIpAndMask(string s, Statistics &sta) {    int i;    int len = s.size();    IP ip;    for (i = 0; i < len; i++) {        if (s[i] == '~') {            break;        }    }    //提取IP地址和子网掩码    ip.ip = s.substr(0, i);    ip.mask = s.substr(i + 1);    //先判断掩码是否有效    if(validMaskAddr(ip.mask) == -1){        sta.ErrIpOrMaskCount++;        return;    }    //再进行IP地址的判断及分类统计    checkIpAddr(ip.ip, sta);    return;}int main() {    string ipInfo;    Statistics sta;    memset(&sta, 0, sizeof(sta));    while (cin >> ipInfo){        getIpAndMask(ipInfo, sta);    }    cout << sta.AIpCount << " " << sta.BIpCount << " " << sta.CIpCount         << " " << sta.DIpCount << " " << sta.EIpCount<< " " << sta.ErrIpOrMaskCount        << " " << sta.PrivateIpCount << endl;    system("pause");    return 0;}

加油!!!!

0 0
原创粉丝点击