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

正则表达式

#include <bitset>
#include <iostream>
#include <iterator>
#include <regex>
#include <sstream>
#include <string>
#include <vector>
using namespace std;
static regex ipRex(
        R"(^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$)");
static regex maskRex(
        R"(^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$)");
bool isValidIP(const string& ip) {
    return regex_match(ip, ipRex);
}

bool isValidMask(const string& mask) {
    if (!regex_match(mask, maskRex)) return false;

    // mask转二进制
    stringstream ss(mask);
    string segment;
    unsigned long binaryMask = 0;
    while (getline(ss, segment, '.')) {
        binaryMask = (binaryMask << 8) | stoi(segment);
    }

    // 判断mask合法
    bitset<32> bit(binaryMask);
    bool zero = false;
    for (int i = 31; i >= 0; --i) {
        if (!bit.test(i)) {
            zero = true;
        } else if (zero) {
            return false;
        }
    }

    return !(binaryMask == 0 || binaryMask == 0xFFFFFFFF);
}

bool isPrivateIP(const string& ip) {
    stringstream ss(ip);
    string segment;
    unsigned long binaryip = 0;
    while (getline(ss, segment, '.')) {
        binaryip = (binaryip << 8) | stoi(segment);
    }

    return (binaryip >= 0x0A000000 && binaryip <= 0x0AFFFFFF) ||
           // 10.0.0.0-10.255.255.255
           (binaryip >= 0xAC100000 && binaryip <= 0xAC1FFFFF) ||
           // 172.16.0.0-172.31.255.255
           (binaryip >= 0xC0A80000 &&
            binaryip <= 0xC0A8FFFF);    // 192.168.0.0-192.168.255.255
}

int main() {
    string a;
    string sub = "~";
    int pos = 0;
    vector<pair<string, string>> temp;
    vector<int> res(7, 0); // A B C D E error privateIP

    while (cin >> a) {
        if ((pos = a.find(sub)) != string::npos) {
            temp.emplace_back(a.substr(0, pos), a.substr(pos + 1, a.size() - 1));
        }
    }

    for (auto it : temp) {
        string ip = it.first;
        string mask = it.second;
        // "0.*.*.*" 和 "127.*.*.*" 的 IP 地址跳过分类
        if (ip.find("0.") == 0 || ip.find("127.") == 0) {
            continue;  
        }
        if (!isValidIP(ip) || !isValidMask(mask)) {
            res[5]++;
            continue;
        }

        stringstream ss(ip);
        string segment;
        unsigned long binaryip = 0;
        while (getline(ss, segment, '.')) {
            binaryip = (binaryip << 8) | stoi(segment);
        }

        if(binaryip >= 0x01000000 && binaryip <= 0x7EFFFFFF){       //A类:"1.0.0.0"-"126.255.255.255"
            res[0]++;
            if(isPrivateIP(ip)) res[6]++;
        }else if (binaryip >= 0x80000000 && binaryip <= 0xBFFFFFFF) { //B类:"128.0.0.0"-"191.255.255.255"
            res[1]++;
            if(isPrivateIP(ip)) res[6]++;
        }else if (binaryip >= 0xC0000000 && binaryip <= 0xDFFFFFFF) { //C类:"192.0.0.0"-"223.255.255.255"
            res[2]++;
            if(isPrivateIP(ip)) res[6]++;
        }else if (binaryip >= 0xE0000000 && binaryip <= 0xEFFFFFFF) { //D类:"224.0.0.0"-"239.255.255.255"
            res[3]++;
        }else if (binaryip >= 0xF0000000 && binaryip <= 0xFFFFFFFF) {  //D类:"240.0.0.0"-"255.255.255.255"
            res[4]++;
        }
    }

    for (auto num : res) {
        cout << num << ' ';
    }
    cout << endl;
    return 0;
}

#C++#
全部评论

相关推荐

弦五Strings:他之所以会举报你代课是因为在这种人眼里正常上课就是正义代课就是邪恶,典型二极管思维,处理方法就是私下沟通,你就说你自己家里经济困难或者家里父母生病什么之类的,需要去打工挣钱,用尽孝的正义对冲他认为的上课的正义,他可能就妥协了。
我的实习日记
点赞 评论 收藏
分享
07-17 12:14
门头沟学院 Java
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务