Page 2 of 2 FirstFirst 12
Results 21 to 27 of 27

Thread: Ip Address Validation

  1. #21
    Join Date
    Apr 2010
    Posts
    4
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Ip Address Validation

    I realize this wins me necro-poster of the year, but I felt that this information would be beneficial to a lot of people.

    The IP Address Validation (by Regex) and Mask issue was a tough cookie to crack. Setting one without the other usually worked but was flawed. I'd either not get the visual effect of having dots in the box or the user could enter invalid addresses (octets with values >255). Setting them together made it impossible to enter any value.

    I found that the Class provided by Wysota solved the problem, but there was another limitation: it required you to use blanks as 0's, when I would prefer to use spaces.

    Side-Note: I know a lot of people are looking for a good IP Address RegEx and here's the best one I've found so far:
    Qt Code:
    1. \b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b
    To copy to clipboard, switch view to plain text mode 

    What I ended up doing was expanding the code that Wysota provided to allow for spaces. Here is the excerpt:
    Qt Code:
    1. if (slist[i].isEmpty() || slist[i] == " ") {
    2. emptyGroup = true;
    3. continue;
    4. }
    To copy to clipboard, switch view to plain text mode 

    Now that fully works with a Mask of "000.000.000.000; " and your users cannot physically enter an invalid address.

    Yay! That is settled. Now for my next problem. My specific programming needs also include being able to enter in a CIDR, which has a Mask of "009.009.009.009\/09". The first part of that works just like IP Addresses and the last part is limited to integers of 0-32.

    To accomplish this, I duplicated Wysota's IP Address class to CIDRValidator. Here is the full code (tested and works):

    Qt Code:
    1. class CIDRValidator : public QValidator {
    2. public:
    3. CIDRValidator(QObject *parent=0) : QValidator(parent) { }
    4. void fixup(QString &/*input*/) const { }
    5. State validate(QString &input, int &/*pos*/) const {
    6. if(input.isEmpty()) { return Acceptable; }
    7. QStringList slist = input.split(".");
    8. int s = slist.size();
    9. if (s > 4) { return Invalid; }
    10. bool emptyGroup = false;
    11. for (int i=0; i<s; i++) {
    12. bool ok, ok2 = true;
    13. QStringList ssplit = slist[i].split('/');
    14. if (slist[i].isEmpty()
    15. || slist[i] == " "
    16. || ssplit.count() > 1 && (ssplit[0] == " " || ssplit[1] == " "))
    17. {
    18. emptyGroup = true;
    19. continue;
    20. }
    21. int val = (ssplit.count() > 1 ? ssplit[0].toInt(&ok) : slist[i].toInt(&ok));
    22. int cidval = (ssplit.count() > 1 ? ssplit[1].toInt(&ok2) : -1);
    23. if((!ok || val<0 || val>255) || (ssplit.count() > 1 && (!ok2 || cidval<0 || cidval>32))) { return Invalid; }
    24. }
    25. if(s<4 || emptyGroup) return Intermediate;
    26. return Acceptable;
    27. }
    28. };
    To copy to clipboard, switch view to plain text mode 

    I hope this information helps future searchers with setting up their own IP Address and CIDR Address boxes.
    Last edited by Jothay; 17th September 2010 at 00:14.

  2. #22
    Join Date
    Jul 2010
    Location
    Ahmedabad,Gujarat,India
    Posts
    25
    Thanks
    14
    Thanked 1 Time in 1 Post
    Qt products
    Qt3 Qt4 Qt/Embedded
    Platforms
    Windows

    Default Re: Ip Address Validation

    With * support class C and D

    class IPV4Validator : public QValidator {
    public:
    IPV4Validator(QObject *parent=0) : QValidator(parent){}
    State validate ( QString & input, int & pos ) const {
    if(input.isEmpty()) return Intermediate;
    QStringList sections = input.split(".");
    if(sections.count()>4)
    return Invalid;
    int newPos = pos;
    int grp = 0;
    bool isEmpty = false;
    while(grp<sections.count()){
    QString txt = sections[grp];
    if(txt.count()>3){
    if(sections.count()==4) return Invalid;
    sections[grp] = txt.left(3);
    sections.insert(grp+1, txt.mid(3));
    newPos++;
    } else if(txt.count()==0){
    isEmpty = true;
    grp++;
    continue;
    }
    txt = sections[grp];
    if(txt[0]=='0' && txt[1]=='0'){
    sections[grp] = '0';
    if(sections.count()<4){
    sections.insert(grp+1, sections[grp]);
    newPos++;
    }
    } else if(txt[0]=='0' && txt.count()>1){
    sections[grp] = txt.mid(1);
    newPos--;
    }
    bool ok;
    int val = txt.toInt(&ok);
    if(!ok)
    {
    if(grp < 2)
    return Invalid;

    if(txt != "*")
    return Invalid;
    }
    if(val>255 && sections.count()<4){
    sections[grp] = txt.left(2);
    sections.insert(grp+1, txt.mid(2));
    val = txt.left(2).toInt();
    newPos++;
    }
    if(val>255||val<0) return Invalid;
    grp++;
    }
    input = sections.join(".");
    // if(newPos==input.count() && sections.count()<4 && input[input.count()-1]!='.' && sections.last().count()==3){
    // newPos++;
    // input += ".";
    // }
    pos = newPos;
    if(sections.count()==4 && !isEmpty) return Acceptable;
    return Intermediate;
    }
    };

  3. #23
    Join Date
    Apr 2010
    Posts
    27
    Thanks
    5
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Ip Address Validation

    Hey everyone,

    Thanks for all the great help.
    I've written some code based on Wysota's work in the previous post. I am implementing the QValidator::fixup() to do some simple alignment and checking of integer checking (The only case when a non integer can be entered is such as "a b", this must be intermediate). The problem is that fixup gets called twice if I press <Enter> to commit the changes to the QLineEdit - displaying two error pop ups. It gets called through two separate events, a keyPressEvent and a focusOutEvent. fixup() is called the second time before it has finished running the first time.

    Qt Code:
    1. void IP4Validator::fixup(QString &input) const
    2. {
    3. QStringList slist = input.split(".");
    4.  
    5. bool intOk;
    6. bool nonIntFound = false;
    7. int s = slist.size();
    8. for(int i=0;i<s;i++){
    9. slist[i].toInt(&intOk);
    10. if(!intOk){
    11. // replace non-integers with a zero value
    12. slist[i] = " 0";
    13. nonIntFound = true;
    14. }
    15. else {
    16. // force right align
    17. slist[i].remove(" ");
    18. slist[i] = slist[i].rightJustified(3,' ');
    19. }
    20. }
    21. input = slist.join(".");
    22. if(nonIntFound){
    23. QMessageBox msgBox;
    24. msgBox.setText("Error: The IPv4 address entered is incorrect");
    25. msgBox.setInformativeText("At least one byte of the address was non-integer, it has now been set to 0. Please check the address");
    26. msgBox.exec();
    27. QApplication::processEvents();
    28. }
    29.  
    30. }
    31.  
    32. IP4Validator::State IP4Validator::validate(QString &input, int &/*pos*/) const {
    33. if(input.isEmpty()) return Acceptable;
    34. QStringList slist = input.split(".");
    35. int s = slist.size();
    36. if(s>4) return Invalid;
    37. bool emptyGroup = false;
    38. bool ok;
    39. for(int i=0;i<s;i++){
    40.  
    41. // This cannot be true with the inputMask set, as there will be space characters
    42. if(slist[i].isEmpty()){
    43. emptyGroup = true;
    44. continue;
    45. }
    46.  
    47. int val = slist[i].toInt(&ok);
    48. if(!ok)
    49. return Intermediate;
    50. else
    51. if(val<0 || val>255)
    52. return Invalid;
    53.  
    54. }
    55. if(s<4 || emptyGroup) return Intermediate;
    56. input = slist.join(".");
    57. return Acceptable;
    58. }
    To copy to clipboard, switch view to plain text mode 

    I considered accessing the type() of the event which called fixup() to filter it but I'm not sure if this is the best way to get around this. Is there something more fundamental with my logic that I have missed here?

    What is the best way to handle this?

    Thanks in advance for your help!

    - Cotlone
    Last edited by Cotlone; 1st November 2010 at 00:08. Reason: spelling corrections

  4. #24
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,368
    Thanks
    3
    Thanked 5,017 Times in 4,793 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Ip Address Validation

    IMO fixup() should not display any pop-ups. It should convert an invalid entry to a valid one. If you want to display a popup, you can handle focusOut()/returnPressed()/whatever, call the validator from there manually and display a popup if the validator claims the entry to be invalid.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  5. #25
    Join Date
    Apr 2010
    Posts
    27
    Thanks
    5
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Ip Address Validation

    I agree, actually, I was thinking that earlier today.
    What do you think about fixup() emitting a signal which can be handled elsewhere? Thanks for your help.

  6. #26
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,368
    Thanks
    3
    Thanked 5,017 Times in 4,793 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Ip Address Validation

    Quote Originally Posted by Cotlone View Post
    What do you think about fixup() emitting a signal which can be handled elsewhere?
    Bad idea. You never know when fixup() might be called and if it started emitting signals in arbitrary moments, it might not be what your users expect.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  7. #27
    Join Date
    Apr 2010
    Posts
    27
    Thanks
    5
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Ip Address Validation

    Ok, good. It did seem a little like bad practise to me.
    Looks like I'll be learning about events now then

Similar Threads

  1. how to read pc's network IP address
    By wei243 in forum Qt Programming
    Replies: 12
    Last Post: 8th January 2010, 16:59
  2. MULTICAST with QT 4.1 and above.
    By jlarsj in forum Qt Programming
    Replies: 7
    Last Post: 10th January 2007, 12:45
  3. How to determine ip address of remote host?
    By nopalot in forum Qt Programming
    Replies: 1
    Last Post: 30th April 2006, 21:18
  4. Problem with mask and validation
    By gunhelstr in forum Qt Programming
    Replies: 1
    Last Post: 19th April 2006, 08:07
  5. Qt 4.1.1 linker warnings
    By Matt Smith in forum Installation and Deployment
    Replies: 0
    Last Post: 26th February 2006, 22:14

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Qt is a trademark of The Qt Company.