2008-11-25 11 views
38

मुझे यह सत्यापित करने की आवश्यकता नहीं है कि आईपी पता पहुंच योग्य है या ऐसा कुछ भी है। मैं सिर्फ यह सत्यापित करना चाहता हूं कि स्ट्रिंग डॉट-क्वाड (xxx.xxx.xxx.xxx) आईपीवी 4 प्रारूप में है, जहां xxx 0 और 255 के बीच है।आप कैसे मान्य करते हैं कि एक स्ट्रिंग C++ में एक वैध आईपीवी 4 पता है?

उत्तर

45

को नंबर दिए गए हैं सकता है, जो रिटर्न नहीं करना चाहते हैं -1 अवैध एएफ तर्क के लिए, अमान्य पते के लिए 0 और वैध आईपी पते के लिए +1। यह आईपीवी 4 और भविष्य के आईपीवी 6 पते दोनों का समर्थन करता है। अगर आपको अभी भी अपना आईपी पता हैंडलिंग लिखना है, तो याद रखें कि एक स्टैंड rd 32-bit हेक्स संख्या एक मान्य आईपी पता है। सभी आईपीवी 4 पते बिंदीदार-दशमलव नोटेशन में नहीं हैं।

यह फ़ंक्शन दोनों पते की पुष्टि करता है, और आपको संबंधित सॉकेट कॉल में एक ही पते का उपयोग करने की अनुमति देता है।

+0

उत्तर देने के लिए धन्यवाद। मैं inet_pton के चारों ओर एक रैपर लिखना समाप्त हो गया। (वास्तव में सरल) कार्यान्वयन के लिए मेरा जवाब देखें। –

+1

** चेतावनी **। दस्तावेज़ों के मुताबिक, यह अवैध एएफ तर्क के लिए -1, अमान्य पते के लिए 0 और मान्य आईपी पते के लिए +1 देता है। –

+0

क्या यह विंडोज़ और लिनक्स प्लेटफॉर्म पर काम करेगा? – impulse

2

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); 
} 
+0

पूरी तरह से सही है क्योंकि यह सत्यापित नहीं करता है कि संख्या में हैं वैध सीमा है, लेकिन इसे ठीक करने के लिए बहुत मुश्किल नहीं होना चाहिए। –

+0

वास्तविक रूप से जांच संख्या एक वैध सीमा में हैं regex में काफी जटिल है। सही रेगेक्स के लिए फेरुसियो का जवाब देखें। –

+0

आप प्रत्येक संख्या को खींचने के लिए REGEX का उपयोग कर सकते हैं, और उसके बाद अंकों के प्रत्येक सेट को उचित सीमा में सुनिश्चित करने के लिए जांच सकते हैं। यह अधिक उपयोगी हो सकता है यदि आप लोगों को उन आईपी में प्रवेश करने से रोकना चाहते हैं जिन्हें बाहरी दुनिया से एक्सेस नहीं किया जा सकता है जैसे कि 127.0.0.1 – Kibbee

2

आप स्वयं वह बजाय तो

atoi() ints अक्षरों परिवर्तित करने के लिए आप प्रत्येक संख्या की सीमा का परीक्षण करने देगा एक पुस्तकालय बारे में उपयोग करना चाहता था, तो और कुछ strcmp के बीच की ' । "के। आप कुछ त्वरित जांच भी कर सकते हैं, जैसे स्ट्रिंग की लंबाई (16 वर्णों से कम (नल टर्मिनेटर सहित), डॉट्स की संख्या आदि होना चाहिए।

लेकिन, संभवतः मौजूदा कोड का उपयोग करना बहुत आसान है।

1

आप बूस्ट या TR1 की भूमि के ऊपर आप डॉट्स के लिए खोज और देखें कि क्या उन दोनों के बीच वर्ण आप शायद inet_pton चाहते 0 से 255

8

यहां एक सीधी विधि है।

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; 
    } 
+1

स्ट्रिंगटोकनाइज़र क्लास से कौन सी लाइब्रेरी आ रही है? –

+19

वहां बहुत सारे हैं, या आप अपना खुद का कार्यान्वयन कर सकते हैं। यहां एक बहुत अच्छा डाउनलोड है जिसे आप डाउनलोड कर सकते हैं: http://www.partow.net/programming/stringtokenizer/index.html (सुनिश्चित करें कि आपके प्रोजेक्ट के लिए लाइसेंस शर्तें स्वीकार्य हैं) – Steve

16

यह भ्रामक सरल लग रहा है लेकिन कुछ नुकसान है। उदाहरण के लिए, पिछले उत्तरों में पोस्ट किए गए कई समाधान मानते हैं कि क्वाड बेस 10 में हैं - लेकिन शून्य से शुरू होने वाला ट्रैक्टर को बेस 8 (ऑक्टल) नंबर के रूप में माना जाना चाहिए, इसलिए उदाहरण के लिए कोई भी क्वाड भाग शून्य और अंक 8 या 9 युक्त मान्य नहीं है। यानी, आईपी नंबर 192.168.1.010नहीं192.168.1.10 है, लेकिन में वास्तविकता 192.168.1.8 है, और आईपी नंबर 192.168.019.14 मान्य नहीं है तीसरे ट्रैक्टर अवैध आधार 8 अंकों शामिल के बाद से 9.

मैं जोरदार ढंग से प्रदान की जाती कार्यों का उपयोग करने के लिए प्रोत्साहित सॉकेट लाइब्रेरी द्वारा आपके ऑपरेटिंग सिस्टम या कंपाइलर वातावरण में शामिल है।

संपादित करें:, (थॉट यह निहित था, लेकिन) निश्चित रूप से आप भी हेक्साडेसिमल quads, एक ला 192.168.1.0x0A 192.168.1.10 के लिए हो सकता है, और निश्चित रूप से आप अपने परपीड़क सामग्री के लिए मिश्रण और मिलान कर सकते हैं खुशी से अपर और लोअर केस का उपयोग कर , 1 9 2.168.1.8 के लिए एक ला 0xC0.0xa8.1.010। यदि आप मस्ती करना चाहते हैं तो पिंग का उपयोग करके कुछ उदाहरण आज़माएं। यह सिर्फ ठीक क्रॉस-प्लेटफार्म काम करता है (लिनक्स, नेटबीएसडी और विन 32 के तहत शपथ ग्रहण करते समय कुछ समय पहले परीक्षण किया गया था।)

KaluSingh गब्बर के अनुरोध के जवाब में

आगे संपादित करें: उदाहरण के लिए, आप 192.168.1.100xc0a8010a के रूप में निर्दिष्ट कर सकते हैं और यह अभी भी एक वैध आईपी नंबर, एक ला प्रतिनिधित्व करता है:

[[email protected] ~]$ 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 
+3

मुझे पता था कि नुकसान थे, लेकिन आपने अभी खोला कीड़े का एक नया नया कर सकते हैं। :) –

+0

हे। मैंने इसके बारे में कठिन तरीका पता चला। आरएफसी ने इसे मिनीटिया विवरण में वर्णित किया है, लेकिन ग्राहक साइट पर किसी उत्पाद को प्रदर्शित करने वाले परेशान प्रबंधक को कुछ भी नहीं बताता है कि "उनमें से 8 या 9 के साथ आईपी पते हमारे ऐप के आईपी एड्रेस नियंत्रण में काम नहीं करते हैं!"एक असंगत समस्या के लिए शिकार मजेदार था ... –

+1

अनुवांशिक: कभी भी यह मानें कि सभी लोग अच्छी तरह से चीजों को व्यवस्थित करने के लिए रिक्त स्थान का उपयोग करते हैं। कुछ शून्य का उपयोग करते हैं। * श्वास * –

29

समाधान है कि मैं था पर बसे:

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; 
} 

यह अन्य उत्तरों में उल्लिखित अधिकांश मामलों के लिए काम करता है। यह ऑक्टल या हेक्स स्वरूपण के साथ आईपी पते को नहीं पहचानता है, लेकिन यह मेरे आवेदन के लिए स्वीकार्य है।

+3

और यह नीचे मतदान हुआ क्योंकि ...? यह ओपी के लिए निश्चित रूप से एक स्वीकार्य जवाब है। :) –

+0

क्या यह आईपीवी 6 का समर्थन करता है? ऐसा नहीं लगता कि यह करता है ... – aberaud

+0

@Wagaf वह आवश्यकताओं में नहीं था। मैंने सवाल अपडेट किया। –

38

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; 

यह भी षोडश आधारी और अष्टाधारी quads के लिए काम करता है। यह भी एक और अधिक पोर्टेबल समाधान है।

+1

+1 का उपयोग करें। बहुत सारे का सबसे अच्छा जवाब। –

+1

@ टोथफू: आपको बूस्ट को इस मुद्दे की रिपोर्ट करनी चाहिए, यह संभवतः एक निरीक्षण है। –

2

मैंने केवल सी स्टडलिब फ़ंक्शंस का उपयोग करके ऐसा ही किया है, यह उपरोक्त वर्णित ऑक्टल क्वाड का समर्थन नहीं करता है, लेकिन यह कोई मुद्दा नहीं होना चाहिए, मैं आसानी से उस हिस्से को जोड़ सकता हूं और आपको दे सकता हूं। एक शुरुआती (छात्र) होने के नाते मुझे अभी तक पता नहीं है कि आपके आईपी के भीतर एक ऑक्टल संख्या प्राप्त करना संभव है। मैंने सोचा कि यह एक दशमलव होना चाहिए।

+1

बिल्कुल बुरा मत मानो। मैंने आपके द्वारा उल्लिखित ऑक्टल संख्याओं सहित, इस प्रश्न से पूछा जाने से पहले यहां वर्णित कई विवरणों से मुझे अनजान रूप से अनजान था। –

0
vector<string> &split(const string &s, char delim, vector<string> &elems) { 
    stringstream ss(s); 
    string item; 
    while(getline(ss, item, delim)) { 
     elems.push_back(item); 
    } 
    return elems; 
} 

vector<string> split(const string &s, char delim) { 
    vector<string> elems; 
    return split(s, delim, elems); 
} 


bool isIPAddress(string ipaddr){ 

    if (ipaddr.length()){ 
      vector<string> _ip=split(ipaddr,'.'); 
      if (_ip.size()==4){ 
        for (int i=0; i < 4; i++){ 
          for (int j=0; j < _ip[i].length(); j++) 
            if (!isdigit(_ip[i][j])) return false; 
          if ((atoi(_ip[i].c_str()) < 0) || (atoi(_ip[i].c_str()) > 255)) return false; 
        } 
      return true; 
      } 
    } 
    return false; 
} 
2

यहां दिए गए आईपीवी 4 पते को सत्यापित करने के लिए सी प्रोग्राम है। मैंने माना है कि आईपी पता दशमलव प्रारूप में है। कृपया मुझे इस पर अपना विचार दें।

// 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"); 
    } 
} 
5

आप विंडोज पर हैं, तो आप WSAStringToAddress का इस्तेमाल करते हैं और वापसी मान हम जानते हैं, अगर पारित तर्क मान्य IP है या नहीं के आधार पर कर सकते हैं। यह विंडोज 2000 के बाद से IPv4 & आईपीवी 6 दोनों का समर्थन करता है।

+4

एक उदाहरण उपयोगी होगा – johannes

1

कुछ मामूली सुधारों 127..0.1, 127.0.0 के रूप में कुछ मामलों को ठीक करने .. और रिक्त स्थान को दूर करता है, तो है:,




    #include <iostream> 
    #include <vector> 
    #include <string> 
    #include <sstream> 
    #include <algorithm> 
    #include <iterator> 
    #include <stdio.h> 

    using namespace std; 

    vector split(char* str, char delimiter) 
    { 
     const string data(str); 
     vector elements; 
     string element; 
     for(int i = 0; i 0) {//resolve problem: 127.0..1 
        elements.push_back(element); 
        element.clear(); 
       } 
      } 
      else if (data[i] != ' ') 
      { 
       element += data[i]; 
      } 

     } 
     if (element.length() > 0)//resolve problem: 127.0..1 
      elements.push_back(element); 
     return elements; 
    } 

    bool toInt(const string& str, int* result) 
    { 
     if (str.find_first_not_of("") != string::npos) 
      return false; 

     stringstream stream(str); 
     stream >> *result; // Should probably check the return value here 
     return true; 
    } 

    /** ipResult: the good ip address, e.g. spaces are removed */ 
    bool validate(char* ip, string *ipResult) 
    { 
     const static char delimiter = '.'; 
     const vector parts = split(ip, delimiter); 
     *ipResult = ""; 
     if (parts.size() != 4) 
      return NULL; 

     for(int i = 0; i 255) 
       return NULL; 

      if (i == 3) { 
       *ipResult += parts[i]; 
      } else { 
       *ipResult += (parts[i] +"."); 
      } 

     } 
     return true; 
    } 

    int main() 
    { 
     string ip; 
     printf("right %d\n", validate("127.0.0.1", &ip)); 
     printf("good ip: %s\n", ip.c_str()); 
     printf("wrong %d\n", validate("127.0.0.-1", &ip)); 
     printf("good ip: %s\n", ip.c_str()); 
     printf("wrong %d\n", validate("127..0.1", &ip)); 
     printf("good ip: %s\n", ip.c_str()); 
     printf("wrong %d\n", validate("...0.1", &ip)); 
     printf("good ip: %s\n", ip.c_str()); 
     printf("wrong %d\n", validate("127.0.0.", &ip)); 
     printf("good ip: %s\n", ip.c_str()); 
     printf("right %d\n", validate("192.168.170.99", &ip)); 
     printf("good ip: %s\n", ip.c_str()); 
     printf("right %d\n", validate("127.0 .0 .1", &ip)); 
     printf("good ip: %s\n", ip.c_str()); 
     printf("\n"); 

     system("pause"); 

     return 0; 
    } 

नहीं
संबंधित मुद्दे