bitset容器和代码计算ip地址

Aki 发布于 2023-12-18 317 次阅读


#include<iostream>
#include<string>
#include<bitset>
#include<cmath>

using namespace std;

struct ip
{
    bitset<8> _1;
    bitset<8> _2;
    bitset<8> _3;
    bitset<8> _4;
};

struct mask
{
    bitset<8> _1;
    bitset<8> _2;
    bitset<8> _3;
    bitset<8> _4;
};

struct address
{
    ip _ip;
    mask _mask;

    friend ostream& operator<<(ostream& os, const address& addr)
    {
        return os << addr._ip._1.to_ulong() << "."
            << addr._ip._2.to_ulong() << "."
            << addr._ip._3.to_ulong() << "."
            << addr._ip._4.to_ulong() << " "
            << addr._mask._1.to_ulong() << "."
            << addr._mask._2.to_ulong() << "."
            << addr._mask._3.to_ulong() << "."
            << addr._mask._4.to_ulong();
    }

    void set_address(const string& addr)
    {
        //192.168.10.11 255.255.255.0
        int arr[6] = { 0 }, pos = 0, s = 0;
        for (int i = 0; i < addr.size(); ++i)
        {
            if (addr[i] == '.')
            {
                arr[pos++] = i;
            }
            if (addr[i] == ' ')
            {
                s = i;
            }
        }
        _ip._1 = stoul(addr.substr(0, arr[0]));
        _ip._2 = stoul(addr.substr(arr[0] + 1, arr[1]));
        _ip._3 = stoul(addr.substr(arr[1] + 1, arr[2]));
        _ip._4 = stoul(addr.substr(arr[2] + 1, s));
        _mask._1 = stoul(addr.substr(s + 1, arr[3]));
        _mask._2 = stoul(addr.substr(arr[3] + 1, arr[4]));
        _mask._3 = stoul(addr.substr(arr[4] + 1, arr[5]));
        _mask._4 = stoul(addr.substr(arr[5] + 1, addr.size() - arr[4]));
    }

    //求网络地址
    address network_address() const
    {
        address addr;
        addr._ip._1 = _ip._1 & _mask._1;
        addr._ip._2 = _ip._2 & _mask._2;
        addr._ip._3 = _ip._3 & _mask._3;
        addr._ip._4 = _ip._4 & _mask._4;
        addr._mask._1 = _mask._1;
        addr._mask._2 = _mask._2;
        addr._mask._3 = _mask._3;
        addr._mask._4 = _mask._4;
        return addr;
    }

    //求广播地址
    address broadcast_address() const
    {
        address addr = network_address();
        addr._ip._1 = addr._ip._1 | (~_mask._1);
        addr._ip._2 = addr._ip._2 | (~_mask._2);
        addr._ip._3 = addr._ip._3 | (~_mask._3);
        addr._ip._4 = addr._ip._4 | (~_mask._4);
        return addr;
    }

    //求第一个可用地址
    address first_available_address()const
    {
        address addr = network_address();
        int val = addr._ip._4.to_ulong();
        addr._ip._4 = addr._ip._4.to_ulong() + 1;
        return addr;
    }

    //求最后一个可用地址
    address last_available_address()const
    {
        address addr = broadcast_address();
        int val = addr._ip._4.to_ulong();
        addr._ip._4 = addr._ip._4.to_ulong() - 1;
        return addr;
    }

    //求可用地址数量
    uint32_t available_address() const
    {
        uint32_t count = 0, n = 0;
        n += _mask._1.count();
        n += _mask._2.count();
        n += _mask._3.count();
        n += _mask._4.count();
        n = 32 - n;
        return pow(2, n) - 2;
    }

    //求地址数量
    uint32_t total_address() const
    {
        return available_address() + 2;
    }

    //求子网数量
    uint32_t subnet()const
    {
        uint32_t  n = 0;
        n += _mask._1.count();
        n += _mask._2.count();
        n += _mask._3.count();
        n += _mask._4.count();
  
        if (n >= 8 && n < 16)
        {
            return pow(2, n - 8);
        }
        else if (n >= 16 && n < 24)
        {
            return pow(2, n - 16);
        }
        else if (n >= 24 && n < 32)
        {
            return pow(2, n - 24);
        }
        else
        {
            return 0;
        }
    }
};

int main()
{

    address addr;
    addr.set_address("10.10.255.192 255.255.128.0");
    cout << addr << endl;

    cout << addr.network_address() << endl;
    cout << addr.broadcast_address() << endl;
    cout << addr.first_available_address() << endl;
    cout << addr.last_available_address() << endl;
    cout << addr.available_address() << endl;
    cout << addr.total_address() << endl;
    cout << addr.subnet() << endl;

}