On Thu, Jul 03, 2003 at 05:19:02AM +0900, Josef 'Jupp' Schugt wrote:
> * 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)

Yeah, I ended up writing something like that. I just wondered if there was
any built-in library function which would do it.

> ~0 >> s << s
> 
> generates a number of all but the last s bits equal one.

That's rather dodgy, notice that the first shift is unnecessary:

irb(main):002:0> ~0      
=> -1
irb(main):003:0> ~0 >> 3
=> -1
irb(main):004:0> ~0 >> 3 << 3
=> -8

(I think you have been following C source code too closely, but even then
I'm not sure if the result of right-shifting a signed value is
implementation-dependent)

I decided to avoid negative numbers altogether, since Ruby is not C with its
32-bit wraparound, so I did

  mask = (0xffffffff << s) & 0xffffffff

> 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.

Or more simply:

   (ipbin & mask) != rbin

Regards,

Brian.