From: Josef 'Jupp' Schugt Date: 2003-07-03T05:19:02+09:00 Subject: Re: IP arithmetic Saluton! * Brian Candler; 2003-07-02, 10:46 UTC: > if ip_match("1.2.3.4", "1.2.3.0/24") > ... etc > end > > and the efficient way of doing this would be to do bitwise operations on the > numeric form. Like the following? def ipmatch(ip, net) unless ip =~ /^(((1?\d|2[0-4])?\d|25[0-5])\.){3}((1?\d|2[0-4])?\d|25[0-5])$/ or net =~ /^(((1?\d|2[0-4])?\d|25[0-5])\.){3}((1?\d|2[0-4])?\d|25[0-5])\/([12]?\d|3[0-2])$/ raise ArgumentError end /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/.match(ip) ipbin = $4.to_i + 256 * ($3.to_i + 256 * ($2.to_i + 256 * $1.to_i)) /(\d+)\.(\d+)\.(\d+)\.(\d+)\/(\d+)/.match(net) rbin = $4.to_i + 256 * ($3.to_i + 256 * ($2.to_i + 256 * $1.to_i)) s = 32 - $5.to_i (ipbin ^ rbin) & (~0 >> s << s) == 0 end Some comments: The lengthy regex ensure that the IP consists of four numbers in the 0.255 range and that the net consists of the same followed by a slash followed by a number in the range 0..32 where zero is the whole IPv4 Internet. The first match assigns each number to an individual string; the next line convert's form base 256 to base 10 using Horner's scheme (quite efficient). Next two lines do the same for net but additionally assign the number of bits to an additional variable. ~0 >> s << s generates a number of all but the last s bits equal one. The whole meaning of (ipbin ^ rbin) & (~0 >> s << s) == 0 is: Find all bits that ipbin and rbin differ in, ignore all that are allowed to be different and see if there are any left. Port from C :-> Gis, Josef 'Jupp' Schugt -- Someone even submitted a fingerprint for Debian Linux running on the Microsoft Xbox. You have to love that irony :). -- Fyodor on nmap-hackers@insecure.org