Как вы проверяете, что строка является действительным адресом IPv4 в C ++? - PullRequest
44 голосов
/ 25 ноября 2008

Мне не нужно проверять, что IP-адрес доступен или что-то в этом роде. Я просто хочу проверить, что строка в точечном квадрате (xxx.xxx.xxx.xxx) в формате IPv4, где xxx находится между 0 и 255.

Ответы [ 17 ]

51 голосов
/ 25 ноября 2008

Возможно, вам нужен inet_pton , который возвращает -1 для недопустимого аргумента AF, 0 для неверного адреса и +1 для действительного IP-адреса. Он поддерживает как IPv4, так и будущие IPv6-адреса. Если вам все еще нужно написать собственную обработку IP-адреса, помните, что стандартное 32-разрядное шестнадцатеричное число является действительным IP-адресом. Не все адреса IPv4 указаны в десятичном формате с точками.

Эта функция одновременно проверяет адрес, а также позволяет использовать один и тот же адрес в связанных вызовах сокетов.

44 голосов
/ 27 октября 2009

Boost.Asio предоставляет класс ip :: address . Если вы просто хотите проверить строку, вы можете использовать ее следующим образом:

std::string ipAddress = "127.0.0.1";
boost::system::error_code ec;
boost::asio::ip::address::from_string( ipAddress, ec );
if ( ec )
    std::cerr << ec.message( ) << std::endl;

Это также работает для шестнадцатеричных и восьмеричных четырехугольников. Это также гораздо более портативное решение.

35 голосов
/ 02 декабря 2008

Решение, на котором я остановился, было:

bool Config::validateIpAddress(const string &ipAddress)
{
    struct sockaddr_in sa;
    int result = inet_pton(AF_INET, ipAddress.c_str(), &(sa.sin_addr));
    return result != 0;
}

Это работает для большинства случаев, которые были упомянуты в других ответах. Он не распознает IP-адреса в восьмеричном или шестнадцатеричном формате, но это приемлемо для моего приложения.

17 голосов
/ 25 ноября 2008

Это выглядит обманчиво простым, но имеет несколько подводных камней. Например, во многих решениях, опубликованных в предыдущих ответах, предполагается, что квады находятся в базе 10 - но квад, начинающийся с нуля , должен рассматриваться как число 8 (восьмеричное), отсюда, например, любое четверная часть, начинающаяся с нуля и содержащая цифры 8 или 9, недопустима. То есть, IP-номер 192.168.1.010 равен , а не 192.168.1.10, но в действительности равен 192.168.1.8, а IP-номер 192.168.019.14 недопустим, поскольку третий квад содержит недопустимую основную 8-значную цифру 9.

Я настоятельно рекомендую вам использовать функции, предоставляемые библиотекой сокетов, включенной в вашу операционную систему или среду компилятора.

Редактировать: (думал, что это было неявно, но) конечно, вы также можете иметь шестнадцатеричные квадраты, а-ля 192.168.1.0x0A для 192.168.1.10, и, конечно, вы можете счастливо смешивать и сопоставлять свой садистский контент, используя верхний и нижний кейс, а-ля 0xC0.0xa8.1.010 для 192.168.1.8. Попробуйте несколько примеров использования ping, если вы хотите повеселиться. Это прекрасно работает на кроссплатформенности (проверено некоторое время назад при ругательствах под Linux, NetBSD и Win32.)

Дальнейшее редактирование в ответ на запрос KaluSingh Gabbar: Например, вы можете указать 192.168.1.10 как 0xc0a8010a, и он по-прежнему представляет действительный IP-номер, например:

[mihailim@home ~]$ ping 0xc0a8010a
PING 0xc0a8010a (192.168.1.10) 56(84) bytes of data.
^C
--- 0xc0a8010a ping statistics ---
3 packets transmitted, 0 received, 100% packet loss, time 2479ms
8 голосов
/ 25 ноября 2008

Вот один простой метод.

bool IsIPAddress(std::string & ipaddr)
    {    

    StringTokenizer quads(ipaddr,".");

    if (quads.countTokens() != 4) return false;

    for (int i=0; i < 4; i++)
      {
      std::string quad = quads.nextToken();
      for (int j=0; j < quad.length(); j++
         if (!isdigit(quad[j])) return false;

      int quad = atoi(quads.GetTokenAt(i));
      if (quad < 0) || (quad > 255)) return false;
      }

    return true;
    }
5 голосов
/ 22 октября 2012

Если вы находитесь в Windows, вы можете использовать WSAStringToAddress и на основе возвращаемого значения, которое мы знаем, если переданный аргумент является действительным IP или нет. Это поддерживает как IPv4, так и IPv6 начиная с Windows 2000 и далее.

2 голосов
/ 25 ноября 2008

Если вы хотите написать это самостоятельно, а не использовать библиотеку, тогда

atoi () для преобразования символов в целые позволит вам проверить диапазон каждого числа и некоторые strcmp между ".". Вы также можете сделать несколько быстрых проверок, таких как длина строки (должна быть менее 16 символов (не включая нулевой терминатор), количество точек и т. Д.

Но, вероятно, НАМНОГО проще использовать существующий код.

2 голосов
/ 25 ноября 2008

Boost.Regex будет уместно.

bool validate_ip_address(const std::string& s)
{
   static const boost::regex e("\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}");
   return regex_match(s, e);
}
2 голосов
/ 18 апреля 2012

Вот программа на C для проверки заданного адреса IPV4. Я предположил, что IP-адрес в десятичном формате. Пожалуйста, дайте мне свои мысли по этому поводу.

  // strTokenFunction.cpp : Check if the specified address is a valid numeric IP address.
  // This function is equavalent to the IPAddress.TryParse() method in C#

#include "stdafx.h"
#include <stdio.h>
#include <conio.h>
#include <string.h>

bool isValidIpAddress(char *st)
{
    int num, i, len;
    char *ch;

    //counting number of quads present in a given IP address
    int quadsCnt=0;

    printf("Split IP: \"%s\"\n", st);

    len = strlen(st);

    //  Check if the string is valid
    if(len<7 || len>15)
        return false;

    ch = strtok(st, ".");

    while (ch != NULL) 
    {
        quadsCnt++;
        printf("Quald %d is %s\n", quadsCnt, ch);

        num = 0;
        i = 0;

        //  Get the current token and convert to an integer value
        while(ch[i]!='\0')
        {
            num = num*10;
            num = num+(ch[i]-'0');
            i++;
        }

        if(num<0 || num>255)
        {
            printf("Not a valid ip\n");
            return false;
        }

        if( (quadsCnt == 1 && num == 0) || (quadsCnt == 4 && num == 0))
        {
            printf("Not a valid ip, quad: %d AND/OR quad:%d is zero\n", quadsCnt, quadsCnt);
            return false;
        }

        ch = strtok(NULL, ".");
    }

    //  Check the address string, should be n.n.n.n format
    if(quadsCnt!=4)
    {
        return false;
    }

    //  Looks like a valid IP address
    return true;
}

int main() 
{
    char st[] = "192.255.20.30";
    //char st[] = "255.255.255.255";
    //char st[] = "0.255.255.0";

    if(isValidIpAddress(st))
    {
        printf("The given IP is a valid IP address\n"); 
    }
    else
    {
        printf("The given IP is not a valid IP address\n");
    }
}
2 голосов
/ 08 ноября 2009

Я сделал то же самое, используя только функции C stdlib, хотя он не поддерживает восьмеричные четырехугольники, как упомянуто выше, но это не должно быть проблемой, я могу легко добавить эту часть и передать ее вам. Будучи новичком (студентом), я до сих пор даже не знал, что в вашем ip можно получить восьмеричное число. Я думал, что это должен быть десятичный.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...