Определите, является ли строка действительным адресом IPv4 в C - PullRequest
25 голосов
/ 27 апреля 2009

Какой будет хороший способ определить, содержит ли строка адрес IPv4? Должен ли я использовать isdigit()?

Ответы [ 14 ]

0 голосов
/ 03 декабря 2012

inet_addr () намного лучше, чем inet_aton (), для проверки представления IPv4 IP-адреса в представлении чисел и точек.

0 голосов
/ 22 июня 2012

Мне нужно было выяснить, содержит ли входящая строка действительный IP-адрес, и, если так, вернуть указатель на часть входящей строки, которая является действительным IP-адресом. Если нет, возвращает нулевой указатель.

Вот код, который, кажется, работает, хотя еще не был хорошо протестирован, я просто написал его и быстро попробовал. Я еще не добавил проверку для ограничения чисел однобайтовыми значениями, но проверю, чтобы убедиться, что они ограничены трехзначными числами.

int IsDigit(char ch)
{
   int is_digit = 0;
   if ( ch >= '0' && ch <= '9' )
   {
      is_digit = 1;
   }
   return is_digit;
}

#define FIND_IP_START         0
#define FIND_IP_DIGIT         1
#define FIND_IP_DIG_OR_DEC    2
#define FIND_IP_DECIMAL       3
#define FIND_IP_DIG_OR_END    4
#define FIND_IP_END           5
#define FIND_IP_DONE          6

char * StringContainsValidIpAddress(char * input_buf_pointer)
{
   char * pos       = input_buf_pointer;
   int    octets    = 0; 
   int    digits    = 0;
   int    state     = FIND_IP_START;
   char * ip_string = 0;

   char   ch        = *pos; 

   while ( (ch != NULL) && (state != FIND_IP_DONE) )
   {
      switch ( state )
      {
      case FIND_IP_START:
         if ( IsDigit(ch) )
         {
            ip_string = pos;  //potential start of ip string
            digits = 1;   // first digit
            octets = 1;   // of first octet
            state = FIND_IP_DIG_OR_DEC;
         }
         break;
      case FIND_IP_DIGIT:
         if ( IsDigit(ch) )
         {
            digits = 1;    // first digit
            octets++;      // of next octet
            if ( octets == 4 )
            {
               state = FIND_IP_DIG_OR_END;
            }
            else
            {
                   state = FIND_IP_DIG_OR_DEC;
            }
         }
         else
         {
            // Start over
            state = FIND_IP_START;
         }
         break;
      case FIND_IP_DIG_OR_DEC:
         // Here we are looking for another digit 
         // of the same octet or the decimal between 
         // octets.
         if (ch == '.')
         {
               state = FIND_IP_DIGIT;
         }
         else if ( IsDigit(ch) )
         {
            digits++;      // next digit
            if ( digits == 3 )
            {
               state = FIND_IP_DECIMAL;
            }
         }
         else
         {
            // Start over
            state = FIND_IP_START;
         }
         break;
      case FIND_IP_DECIMAL:
         if (ch == '.')
         {
               state = FIND_IP_DIGIT;
         }
         break;
      case FIND_IP_DIG_OR_END:
         // Here we are looking for another digit 
         // of the same octet or the end (which could
         // be a space or CR or LF or really any 
         // non-digit).
         if ( IsDigit(ch) )
         {
            digits++;      // next digit
            if ( digits == 3 )
            {
               state = FIND_IP_END;
            }
         }
         else
         {  
            *pos = 0;  // Null terminate the IP address string
            state = FIND_IP_DONE;
         }
         break;
      case FIND_IP_END:
         if ( !IsDigit(ch) )
         {
            *pos = 0;  // Null terminate the IP address string
            state = FIND_IP_DONE;
         }
         break;
      case FIND_IP_DONE:
         break;
      default:
         break;
      }

      // Fetch the next character
      ch = *++pos; 
   } 

   if (state == FIND_IP_DONE) 
   {
      return ip_string; 
   }
   else
   {
      return 0;
   }
}
0 голосов
/ 22 февраля 2011

Я думаю, что ниже фрагмент кода C должен работать

bool validate_ip4(const char* buffer)
{
    if (NULL == buffer) return false;

    register const      char*   pos     = buffer;
    register unsigned   char    ch      = *pos;
    register unsigned   short   count   = 0;

    while (ch != NULL)
    {
        if (!((ch >= '0' && ch <= '9') || ch == '.')) return false;

        if (ch == '.')
            if (++count > 3) return false;

        ch = *++pos;
    }

    if (count == 3 && *--pos != '.') return true;

    return false;
}
0 голосов
/ 27 апреля 2009

В url / uri rfc 3986 адрес расширенной формы Бэкуса-Наура (ABNF) ipv4 определяется как:

  IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet

  dec-octet   = DIGIT                 ; 0-9
              / %x31-39 DIGIT         ; 10-99
              / "1" 2DIGIT            ; 100-199
              / "2" %x30-34 DIGIT     ; 200-249
              / "25" %x30-35          ; 250-255

Я реализовал проверку с помощью регулярного выражения в следующей форме:

// Although the RFC says ipv6 octects like 001 are not valid, it would be risky
// not to accept those
#define decoct "([01]?[0-9]?[0-9]|2[0-4][0-0]|25[0-5])"
#define ipv4 "(" decoct "\\." decoct "\\." decoct "\\." decoct ")"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...