Jump to content
Sign in to follow this  
enaiman

Check IP format and value

Recommended Posts

enaiman

I haven't been able to find a similar function so I decided to write one.

Because I consider myself less than a "novice" in using Regular Expressions, I'm pretty sure that the RegExp I've used can be greatly improved - any suggestions welcome.

_IsValidIP will check the following:

- no more than 4 numbers

- the four numbers to be between 0-255

- first number can't be 0

- nothing else allowed than digits and "." (white spaces not allowed)

I have tested it and I couldn't find any bugs - if you find any - please let me know.

Example and function code:

Dim $IP_array [6] = ["10.12.15.222", "10. 12.15 .222", "0.12.15.222", "10.01.15.222", "10:12.15.222.11.25", "257.12.15.222"] 

For $i = 0 To UBound($IP_array)-1
    If _IsValidIP($IP_array[$i]) = 1 Then
        MsgBox(0, "Check "&$IP_array[$i], $IP_array[$i]&" is VALID")
    Else
        MsgBox(0, "Check "&$IP_array[$i], $IP_array[$i]&" is INVALID")
    EndIf
Next

; #FUNCTION# ;===============================================================================;
; Name...........: _IsValidIP
; Description ...: Checks if an IP address has a correct format and value
; Syntax.........: _IsValidIP($IPaddr)
; Parameters ....: $IPaddr - IP address to be checked
; Return values .: Success - 1 (Valid format/value)
;                  Failure - Returns 0 and Sets @Error:
;                  |0 - No error.
;                  |1 - Invalid IP address format/value
; Author ........: enaiman
;==========================================================================================
Func _IsValidIP($IPaddr)
    Local $result
    $result = StringRegExp($IPaddr, "\b(25[0-5]\.|2[0-4]\d\.|1\d\d\.|[1-9]\d\.|[1-9]\.){1}((25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)\.){2}(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)\b",2)
    If @error Then 
        Return SetError(1, 0, 0)
    EndIf
    If StringReplace($IPaddr, $result[0], "") <> "" Then
        Return SetError(1, 0, 0)
    Else
        Return SetError(0, 0, 1)
    EndIf
EndFunc
Edited by enaiman

SNMP_UDF ... for SNMPv1 and v2c so far, GetBulk and a new example script

wannabe "Unbeatable" Tic-Tac-Toe

Paper-Scissor-Rock ... try to beat it anyway :)

Share this post


Link to post
Share on other sites
Fulano

A possible alternative:

Dim $IP_array [6] = ["10.12.15.222", "10. 12.15 .222", "0.12.15.222", "10.01.15.222", "10:12.15.222.11.25", "257.12.15.222"] 

For $i = 0 To UBound($IP_array)-1
    If _IsValidIP($IP_array[$i]) = 1 Then
        MsgBox(0, "Check "&$IP_array[$i], $IP_array[$i]&" is VALID")
    Else
        MsgBox(0, "Check "&$IP_array[$i], $IP_array[$i]&" is INVALID")
    EndIf
Next

; #FUNCTION# ;===============================================================================;
; Name...........: _IsValidIP
; Description ...: Checks if an IP address has a correct format and value
; Syntax.........: _IsValidIP($IPaddr)
; Parameters ....: $IPaddr - IP address to be checked
; Return values .: Success - 1 (Valid format/value)
; Failure - Returns 0 and Sets @Error:
; |0 - No error.
; |1 - Invalid IP address format/value
; Author ........: enaiman & Fulano
;==========================================================================================
Func _IsValidIP($IPaddr)
    Local $result = StringRegExp($IPaddr, "(\d+)\.(\d+)\.(\d+)\.(\d+)", 1)
    If @error Then Return SetError(1, 0, 0)
    
    If $result[0] < 1 or $result[0] > 255 Then Return SetError (0, 0, 1) ; Separate test for the first, which has different requirements

    For $index = 1 to Ubound ($result) - 1
    If $result[$index] < 0 or $result[$index] > 255 Then Return SetError (0, 0, 1) ; Fails the test, no need to test further
    Next

    Return SetError(1, 0, 0)
EndFunc
Mainly it simplifies the regex, at the cost of some fairly simple validation


#fgpkerw4kcmnq2mns1ax7ilndopen (Q, $0); while ($l = <Q>){if ($l =~ m/^#.*/){$l =~ tr/a-z1-9#/Huh, Junketeer's Alternate Pro Ace /; print $l;}}close (Q);[code] tag ninja!

Share this post


Link to post
Share on other sites
MrCreatoR

I haven't been able to find a similar function

I found it when tried to search :mellow:

 

Spoiler

Using OS: Win 7 Professional, Using AutoIt Ver(s): 3.3.6.1 / 3.3.8.1

AutoIt_Rus_Community.png AutoIt Russian Community

My Work...

Spoiler

AutoIt_Icon_small.pngProjects: ATT - Application Translate Tool {new}| BlockIt - Block files & folders {new}| SIP - Selected Image Preview {new}| SISCABMAN - SciTE Abbreviations Manager {new}| AutoIt Path Switcher | AutoIt Menu for Opera! | YouTube Download Center! | Desktop Icons Restorator | Math Tasks | KeyBoard & Mouse Cleaner | CaptureIt - Capture Images Utility | CheckFileSize Program

AutoIt_Icon_small.pngUDFs: OnAutoItErrorRegister - Handle AutoIt critical errors {new}| AutoIt Syntax Highlight {new}| Opera Library! | Winamp Library | GetFolderToMenu | Custom_InputBox()! | _FileRun UDF | _CheckInput() UDF | _GUIInputSetOnlyNumbers() UDF | _FileGetValidName() UDF | _GUICtrlCreateRadioCBox UDF | _GuiCreateGrid() | _PathSplitByRegExp() | _GUICtrlListView_MoveItems - UDF | GUICtrlSetOnHover_UDF! | _ControlTab UDF! | _MouseSetOnEvent() UDF! | _ProcessListEx - UDF | GUICtrl_SetResizing - UDF! | Mod. for _IniString UDFs | _StringStripChars UDF | _ColorIsDarkShade UDF | _ColorConvertValue UDF | _GUICtrlTab_CoverBackground | CUI_App_UDF | _IncludeScripts UDF | _AutoIt3ExecuteCode | _DragList UDF | Mod. for _ListView_Progress | _ListView_SysLink | _GenerateRandomNumbers | _BlockInputEx | _IsPressedEx | OnAutoItExit Handler | _GUICtrlCreateTFLabel UDF | WinControlSetEvent UDF | Mod. for _DirGetSizeEx UDF
 
AutoIt_Icon_small.pngExamples: 
ScreenSaver Demo - Matrix included | Gui Drag Without pause the script | _WinAttach()! | Turn Off/On Monitor | ComboBox Handler Example | Mod. for "Thinking Box" | Cool "About" Box | TasksBar Imitation Demo

Like the Projects/UDFs/Examples? Please rate the topic (up-right corner of the post header: Rating AutoIt_Rating.gif)

* === My topics === *

==================================================
My_Userbar.gif
==================================================

 

 

 

AutoIt is simple, subtle, elegant. © AutoIt Team

Share this post


Link to post
Share on other sites
enaiman

@MrCreatoR

Wow - what are the odds that the functions have the same name? I'm really amazed.

When I said I couldn't find a similar one, I've been searching in Example Scripts for title contents, never thought to search other forums as well.

@Fulano

Thank you very much for your suggestion. It is indeed an alternative code and it does work the same. I have used quite a similar approach (function) for a long time. What I really wanted to achieve was the ONLY use of ONE RegEx and nothing else. It turned out that I didn't really succeed because RegEx returned matches (positive results) when the IP string was bigger (10.10.10.10.1.22.55.35 was a match).

I tried using exact numbers {1}, {2}, {1} but it still didn't work.

If any RegEx guru can help me nail this part down (if possible) I would be grateful.

Thanks,


SNMP_UDF ... for SNMPv1 and v2c so far, GetBulk and a new example script

wannabe "Unbeatable" Tic-Tac-Toe

Paper-Scissor-Rock ... try to beat it anyway :)

Share this post


Link to post
Share on other sites
scriptjunkie

I like your solution. The only thing I could come up with was this:

"[1-2][0-9]{0,2}\.[1-2][0-9]{0,2}\.[1-2][0-9]{0,2}\.[1-2][0-9]{0,2}"

But, doesn't work.

Edited by scriptjunkie

Share this post


Link to post
Share on other sites
Inny

This expression should suit your needs.

^([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}$
Accepts any IP address from 0.0.0.0 through 255.255.255.255.

Share this post


Link to post
Share on other sites
enaiman

@Inny - thanks for providing your RegExp - It works nicely ... but it will return VALID for an IP 0.10.20.30. It is a correct IP format but not quite a "valid" one; I haven't seen any IP address having 0 as the first part.

My UDF was not intended to check only the format - it excludes any 0.x.y.z since these are not likely to be used.


SNMP_UDF ... for SNMPv1 and v2c so far, GetBulk and a new example script

wannabe "Unbeatable" Tic-Tac-Toe

Paper-Scissor-Rock ... try to beat it anyway :)

Share this post


Link to post
Share on other sites
spudw2k

@Inny - thanks for providing your RegExp - It works nicely ... but it will return VALID for an IP 0.10.20.30. It is a correct IP format but not quite a "valid" one; I haven't seen any IP address having 0 as the first part.

My UDF was not intended to check only the format - it excludes any 0.x.y.z since these are not likely to be used.

Agreed, No valid IP address can start with 0, nor end with a 0 or 255.

Share this post


Link to post
Share on other sites
wraithdu

Currently checks 1-255.0-255.0-255.0-255 and allows for formats like "01", "001", "010". I need another pair of eyes here before giving this the thumbs up.

"^(25[0-5]|2[0-4][0-9]|1[0-9]{2}|0?[1-9][0-9]?|00[1-9])(\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$"
Edited by wraithdu

Share this post


Link to post
Share on other sites
somdcomputerguy

..No valid IP address can start with 0, nor end with a 0 or 255.

I guess the definition of 'valid' can vary, the Subnet mask of my router ends with a 0.

255.255.255.0

- Bruce /*somdcomputerguy */  If you change the way you look at things, the things you look at change.

Share this post


Link to post
Share on other sites
FranckGr

For those who want to know a bit more on IPV4

First bits....Addresses..............................Class

=================================================================================================================

0.............0.0.0.0-126.255.255.255................CLASS A (MASK 255.0.0.0)

................0.0.0.0..................................Any Local NIC

................0.0.0.0-0.255.255.255....................Local host addresses (0/8)

................0.0.0.0-10.255.255.255...................Local network only (10/8)

..............127.0.0.0-127.255.255.255..............Local host addresses (127/8)

0111 1111.......127.0.0.1................................Localhost (MASK 255.0.0.1)

10............128.0.0.0-191.255.255.255..............CLASS B (MASK 255.255.0.0)

................169.254.0.0-169.254.255.255..............Automatic NIC configuration (Local network)(169.254/16)

................172.16.0.0-172.31.255.255................Local network only (172.16/12)

110...........192.0.0.0-223.255.255.255..............CLASS C (MASK 255.255.255.0)

................192.168.0.0-192.168.255.255..............Local network only (192.168/16)

1110..........224.0.0.0-247.255.255.255..............CLASS D (Multicast Addresses - Destination Addresses only)

1111..........240.0.0.0-247.255.255.255..............CLASS E (Research - Should be Ignored)

..............255.255.255.255........................Broadcast address

So it should be something like that for a (Source) host

1-223 . 1-254 . 1-254 . 1-254

But not

127.x.x.x

169.254.X.X

Share this post


Link to post
Share on other sites
wraithdu

Well, if someone can come up with the valid patterns for each octet, I can tweak it. Otherwise it's set at 1-255.0-255.0-255.0-255. Oh, and I fixed an earlier brain fart too...

edit\

Gah, fixed again... I suck today.

Edited by wraithdu

Share this post


Link to post
Share on other sites
enaiman

Thanks all for input.

@wraithdu

Tested your pattern and as you said - 01, 010 ... are returned as valid; unfortunately that doesn't look like a correct IP. I agree - it might work but for me at least it "doesn't look" like a "normal" IP.

@FranckGr

So it should be something like that for a (Source) host

1-223 . 1-254 . 1-254 . 1-254

But not

127.x.x.x

169.254.X.X

The first part is easy to implement, just change the limits on the RegEx.

The next part - exclusions - it can be done via some extra If's. If the other users agree to this way, I;m glad to do it.


SNMP_UDF ... for SNMPv1 and v2c so far, GetBulk and a new example script

wannabe "Unbeatable" Tic-Tac-Toe

Paper-Scissor-Rock ... try to beat it anyway :)

Share this post


Link to post
Share on other sites
wraithdu

Yeah, 008.008.008.008 doesn't look right, and the IP settings dialog for a network adapter will auto-correct it, but it WILL let you enter it as valid.

Share this post


Link to post
Share on other sites
FranckGr

>> Tested your pattern and as you said - 01, 010 ... are returned as valid; unfortunately that doesn't look like a correct IP. I agree - it might work but for me at least it "doesn't look" like a "normal" IP.

Try http://087.106.244.038/forum//index.php ...

Share this post


Link to post
Share on other sites
jchd

Here's a less than perfect contribution to classify and characterize an IPv4 address:

#cs
000.000.000.000                         class A any local NIC
000.000.000.001     000.255.255.255     class A local host
000.000.000.000     010.255.255.255     class A local network
000.000.000.000     126.255.255.255     class A
127.000.000.001                         local host
127.000.000.000     127.255.255.255     local host addresses
169.254.000.000     169.254.255.255     class B automatic local NIC configuration
172.016.000.000     172.031.255.255     class B local network
128.000.000.000     191.255.255.255     class B
192.168.000.000     192.168.255.255     class C local network
192.000.000.000     223.255.255.255     class C
224.000.000.000     239.255.255.255     class D multicast destination address
240.000.000.000     247.255.255.255     class E research
248.000.000.000     254.255.255.255     unassigned
255.255.255.255                         broadcast address
#ce

Global Enum _
    $IPv4_Invalid                   = 0x00000000, _
    $IPv4_Class_A_AnyLocalNIC   = 0x00010017, _
    $IPv4_Class_A_LocalHost         = 0x00010027, _
    $IPv4_Class_A_LAN               = 0x00010103, _
    $IPv4_Class_A                   = 0x00010403, _
    $IPv4_LocalHost_1               = 0x00000067, _
    $IPv4_LocalHost                 = 0x00000027, _
    $IPv4_Class_B_LAN_AutoConfig    = 0x00020203, _
    $IPv4_Class_B_LAN               = 0x00020103, _
    $IPv4_Class_B                   = 0x00020403, _
    $IPv4_Class_C_LAN               = 0x00040103, _
    $IPv4_Class_C                   = 0x00040403, _
    $IPv4_Class_D_MulticastDest     = 0x00080807, _
    $IPv4_Class_E_Research          = 0x00100004, _
    $IPv4_Unassigned                = 0x00200004, _
    $IPv4_Broadcast                 = 0x00001005, _
    $IPv4_Type_Valid                = 0x00000001, _
    $IPv4_Type_Usable               = 0x00000002, _
    $IPv4_Type_Special              = 0x00000004, _
    $IPv4_Type_LocalNIC             = 0x00000010, _
    $IPv4_Type_LocalHost            = 0x00000020, _
    $IPv4_Type_LocalHost1           = 0x00000060, _
    $IPv4_Type_LAN                  = 0x00000100, _
    $IPv4_Type_AutoConfig           = 0x00000200, _
    $IPv4_Type_Generic              = 0x00000400, _
    $IPv4_Type_Multicast            = 0x00000800, _
    $IPv4_Type_Broadcast            = 0x00001000, _
    $IPv4_Type_Class_A              = 0x00010000, _
    $IPv4_Type_Class_B              = 0x00020000, _
    $IPv4_Type_Class_C              = 0x00040000, _
    $IPv4_Type_Class_D              = 0x00080000, _
    $IPv4_Type_Class_E              = 0x00100000, _
    $IPv4_Type_Class_Other          = 0x00200000 _

Local $str = " 192 .0000168. 1 . 0000000131 "
Local $ret = IP4class($str)
ConsoleWrite('<' & $str & '> flags=' & Hex(@extended) & ' ' & $ret & @LF)
Exit

Func IP4class($s)
    If Not IsString($s) Then Return(SetError(1, $IPv4_Invalid, ''))
    Local $res = StringRegExp($s, "(\d+)(?:\s*?.\s*?|\s*?$)", 3)
    Local $ip, $class

    For $val In $res
        If $val > 255 Then Return(SetError(2, $IPv4_Invalid, ''))
        $ip = BitShift($ip, -8) + $val
    Next

    Switch $ip
        Case 0x00000000
            $class = $IPv4_Class_A_AnyLocalNIC

        Case 0x00000001 To 0x00ffffff
            $class = $IPv4_Class_A_LocalHost

        Case 0x01000000 To 0x0affffff
            $class = $IPv4_Class_A_LAN

        Case 0x0b000000 To 0x7effffff
            $class = $IPv4_Class_A

        Case 0x7f000001
            $class = $IPv4_LocalHost_1

        Case 0x7f000000 To 0x7fffffff
            $class = $IPv4_LocalHost

        Case 0xa9fe0000 To 0xa9feffff
            $class = $IPv4_Class_B_LAN_AutoConfig

        Case 0xac100000 To 0xac1fffff
            $class = $IPv4_Class_B_LAN

        Case 0x80000000 To 0xbfffffff
            $class = $IPv4_Class_B

        Case 0xc0a80000 To 0xc0a8ffff
            $class = $IPv4_Class_C_LAN

        Case 0xc0000000 To 0xdfffffff
            $class = $IPv4_Class_C

        Case 0xe0000000 To 0xefffffff
            $class = $IPv4_Class_D_MulticastDest

        Case 0xf0000000 To 0xf7ffffff
            $class = $IPv4_Class_E_Research

        Case 0xf8000000 To 0xfffffffe
            $class = $IPv4_Unassigned

        Case 0xffffffff
            $class = $IPv4_Broadcast
    EndSwitch
    Return(SetError(0, $class, StringFormat("%u.%u.%u.%u", $res[0], $res[1], $res[2], $res[3])))
EndFunc

The code is self-explanatory. The $IPv4_Type* bits may be used to test individual characteristics. The 'usable' bit is meant to denote an address you can actually use in practice, whatever that means. Note that subnet local bradcast addresses depend on network mask so this bit being 0 doesn't mean the address isn't a broadcast address in the particular network you consider.

The order of CASEs is such that it allows for range inclusions easily. Same for head comments ranges.

Network gurus can probably correct/expand that function.

To enaiman and Regexp maniacs: I mildly believe the whole function could be turned into a single AutoIt line using some really insane regexp, but don't count on me to spell it for you :idea:

Edited by jchd

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.