Как увеличить IP-адрес, представленный в виде строки? - PullRequest
6 голосов
/ 01 октября 2009

У меня есть IP-адрес типа char Как char ip = "192.123.34.134" Я хочу увеличить последнее значение (134). У кого-нибудь как мне это сделать? Я думаю, я должен преобразовать его в целое число, а затем обратно, но, к сожалению, я не знаю, как? :( Я использую C ++.

Пожалуйста, помогите мне!

Спасибо, Кампи

Ответы [ 7 ]

24 голосов
/ 01 октября 2009

Вы можете преобразовать IP-адрес из строки в целое число, используя inet_addr, а затем, после манипулирования им, преобразовать его обратно в строку с inet_ntoa.

См. документацию для этих функций для получения дополнительной информации о том, как их использовать.

Вот небольшая функция, которая будет делать то, что вы хотите:

// NOTE: only works for IPv4.  Check out inet_pton/inet_ntop for IPv6 support.
char* increment_address(const char* address_string)
{
    // convert the input IP address to an integer
    in_addr_t address = inet_addr(address_string);

    // add one to the value (making sure to get the correct byte orders)
    address = ntohl(address);
    address += 1;
    address = htonl(address);

    // pack the address into the struct inet_ntoa expects
    struct in_addr address_struct;
    address_struct.s_addr = address;

    // convert back to a string
    return inet_ntoa(address_struct);
}

Включить <arpa/inet.h> в * nix системах или <winsock2.h> в Windows.

4 голосов
/ 01 октября 2009

Quick / Грязный!

void increment(std::string& ip)
{
    std::string::size_type dot = ip.find_last_of('.');
    std::stringstream stream(ip.substr(dot+1));
    int part = 0;

    stream >> part;

    part++;

    stream.str(""); stream.clear();

    stream << part;

    ip.replace(dot+1, std::string::npos, stream.str());
}
3 голосов
/ 01 октября 2009
int a,b,c,d;
sscanf(str, "%d.%d.%d.%d", &a,&b,&c,&d);
sprintf(str, "%d.%d.%d.%d\0", a,b,c,d+1);
2 голосов
/ 01 октября 2009

Я бы написал метод, который принимает строку в этом формате.
Преобразуйте его в 4 целых числа. приращение. (Важный диапазон проверки)
Затем преобразуйте обратно в строку.

Если вы хотите что-то более долгосрочное и надежный класс, представляющий IP-адрес. Затем вы сохраняете класс как подходящий и конвертируете в строку при необходимости.

#include <iostream>
#include <istream>
#include <sstream>
#include <string>
#include <stdexcept>



class MyIp
{
    struct Dot
    {};
    struct Byte
    {
        Byte(unsigned char& val)
            :m_val(val)
        {}
        unsigned char&  m_val;
    };
    friend std::istream& operator>>(std::istream& str,MyIp::Dot const& d);
    friend std::istream& operator>>(std::istream& str,MyIp::Byte const& b);
    friend std::ostream& operator<<(std::ostream& str,MyIp const& ip);
    public:
        MyIp(std::string const& ip)
        {
            std::stringstream str(ip);
            str >> Byte(ad[0]) >> Dot() >> Byte(ad[1]) >> Dot() >> Byte(ad[2]) >> Dot() >> Byte(ad[3]);
            std::string leftover;
            if (str >> leftover)
            {   throw std::runtime_error("InvalidIP: Long");
            }
        }
        void inc(int index)
        {
            if ((index >= 0) && (index <=3))
            {
                ++ad[index];
                if (ad[index] == 0)
                {
                    inc(index-1);
                }
            }
        }
    private:
        unsigned char   ad[4];
};
std::istream& operator>>(std::istream& str,MyIp::Dot const& d)
{
    char x  = str.get();
    if (x != '.')
    {   throw std::runtime_error("Invalid IP: Dot");
    }
    return str;
}
std::istream& operator>>(std::istream& str,MyIp::Byte const& b)
{
    unsigned int val;
    str >> val;
    if (!str || val > 255)
    {   throw std::runtime_error("Invalid IP: Val");
    }
    b.m_val = static_cast<unsigned char>(val);
    return str;
}
std::ostream& operator<<(std::ostream& str,MyIp const& ip)
{
    return str  << static_cast<unsigned int>(ip.ad[0])
                << "." << static_cast<unsigned int>(ip.ad[1])
                << "." << static_cast<unsigned int>(ip.ad[2])
                << "." << static_cast<unsigned int>(ip.ad[3]);
}

int main()
{
    try
    {
        std::string ip("127.0.0.1");

        MyIp    addr(ip);

        std::cout << addr << "\n";
        addr.inc(3);
        std::cout << addr << "\n";
    }
    catch(std::exception const& e)
    {
        std::cout << "What: " << e.what() << "\n";
    }
}
0 голосов
/ 01 октября 2009

Это, наверное, не очень вменяемое, но об этом было интересно думать.

Поскольку пространство IP-адресов является 32-разрядным, вы можете написать функцию для преобразования IP-адресов в 32-разрядные целые числа без знака. Затем вы можете добавить или вычесть 1 или столько, сколько хотите, и преобразовать обратно в IP-адрес. Вам не придется беспокоиться о проверке диапазона.

В псевдокоде для 192.123.34.134 вы должны сделать:

int i = (192 << 24) + (123 << 16) + (34 << 8) + 134

В целом, для a.b.c.d:

int i = (a << 24) + (b << 16) + (c << 8) + d

Теперь измените i столько, сколько хотите (i++, i+=10000) и конвертируйте обратно:

String ip = (i >> 24) + "." + 
            ((i >> 16) mod 256) + "." + 
            ((i >> 8) mod 256) + "." + 
            (i mod 256);

Извините за синтаксис - я не мог написать C ++, чтобы спасти себя.

MK

0 голосов
/ 01 октября 2009

Вы также можете использовать местоположение последнего "." и взять оттуда до конца, чтобы преобразовать в int, увеличить его 1, проверить границы, а затем преобразовать его в строку и добавить к базовой части.

0 голосов
/ 01 октября 2009

Этот сайт съел мои вкладки, поэтому я попробую еще раз. Я уверен, что есть библиотека, которая делает что-то подобное, но это должно работать (при условии, что мой синтаксис не испорчен) достаточно, чтобы донести идею.

Псевдокод:

char[] ipAddress= "192.123.34.134";

if (ipAddress[ipAddress.Length-1] == '9')
{
    if(ipAddress[ipAddress.Length-2]=='9')
    {
        ipAddress[ipAddress.Length-1]='0';
        ipAddress[ipAddress.Length-2]='0';
        ipAddress[ipAddress.Length-3]=(char)ipAddress[ipAddress.Length-3]+1;
    }
    else
    {
        ipAddress[ipAddress.Length-2]=(char)ipAddress[ipAddress.Length-2]+1;
        ipAddress[ipAddress.Length-1]='0';
    }
}
else
{
     ipAddress[ipAddress.Length-1]=(char)ipAddress[ipAddress.Length-1]+1;
}
...