note 83256 deleted from function.ip2long by danbrown

From: Date: Fri, 05 Dec 2008 13:28:40 +0000
Subject: note 83256 deleted from function.ip2long by danbrown
References: 1  Groups: php.notes 
Request: Send a blank email to php-notes+get-147682@lists.php.net to get a copy of this message
Note Submitter: mike at hotmail dot com ---- one tiger one: Your netmask function almost works. Unfortunately, for the 2 outlying netmasks, it doesn't. There are only 33 valid netmasks: a netmask has to look like this (in binary) 00000000000000000000000000000000 zero 10000000000000000000000000000000 1 1 followed by 31 0's 11000000000000000000000000000000 2 1s followed by 30 0's 11100000000000000000000000000000 3 1s followed by 29 0's 11110000000000000000000000000000 4 1s followed by 28 0's 11111000000000000000000000000000 5 1s followed by 27 0's etc. (the 1's keep growing by 1, the 0's shrinking by 0). lastly: 11111111111111111111111111111111 32 1s followed by 0 0's The netmasks above translate to: 0.0.0.0 128.0.0.0 192.0.0.0 224.0.0.0 240.0.0.0 248.0.0.0 ... 255.255.255.255 Your function does not accept 0.0.0.0 or 255.255.255.255 which are both valid netmasks. the 0.0.0.0 case fails because you are not comparing with === to FALSE, but are using ! with ip2long. ip2long for 0.0.0.0 returns 0, which is read as FALSE so the ! succeeds. The 255.255.255.255 case fails because your 2nd elseif checks to make sure there is at least one 0 in the binary representation of the netmask, which is not a valid test for 255.255.255.255 (In fact, I'm not sure why this check was put in there). I've computed the ip2long only once, as well as the decbin only once, to make it a bit faster. (It's faster for valid netmasks, a bit slower with invalid bitmasks. I just don't like computing the same value more than once) function checkNetmask4($ip) { $ip2long = ip2long($ip); $decbin = decbin($ip2long); if ($ip2long === FALSE) { return false; } elseif(strlen($decbin) != 32 && $ip2long != 0) { return false; } elseif(ereg('01',$decbin)) { return false; } else { return true; } } I ran through all 2+ billion netmasks, and verified that this code works, returning true 33 times for the correct netmasks (1 core fully maxed for approx 9.5 hours at 1.8Ghz for anyone who cares). The PEAR Net_IPv4 package has a validateNetmask function which does an explicit comparison to the 33 valid netmasks, which can also be poached. I ran this code against it for 100,000 iterations, and for invalid netmasks, this code is twice as fast. For valid netmasks, it depends on where in Net_IPv4's list the netmask is...ones further down the list take longer, as it is doing up to 33 compares. For 0.0.0.0 the PEAR code is better than twice as fast, as 0.0.0.0 is the first element in the array. For 255.255.255.255 this code is twice as fast, as it's the last element in the PEAR codes array. I'm not saying you should use this code or PEARs, I just didn't want anyone to use the faulty code below. NOT my real email.

« previous php.notes (#147682) next »