On Tue, Jul 21, 2020 at 02:17:59AM +0800, Ben Coman wrote:

> On Mon, 20 Jul 2020 at 23:19, Sean P. DeNigris <

[hidden email]> wrote:

> >

> > I want to take an IP address routing prefix in CIDR [1] notation (i.e. the 24

> > in "192.168.100.14/24") and convert it into subnet form (i.e.

> > 255.255.255.0). I came up with 4 ways to do that (see below), but none stand

> > out as best (although #3 and #4 seem a bit more straightforward as they

> > avoid the `max` temp).

> >

> > How would you go about it?

> >

> > Here are the ways I came up with:

> > cidr := 24.

> > shift := 32 - cidr.

> > max := #[ 255 255 255 255 ] asInteger.

> > "1." ((max bitShift: shift negated) bitShift: shift) asByteArray.

> > "2." (max bitClear: (2 raisedTo: shift) - 1) asByteArray.

> > "3." ((2 raisedTo: shift) - 1) bitInvert32 asByteArray.

> > "4." (((2 raisedTo: cidr) - 1) bitShift: shift) asByteArray

>

> To me the most complicated ones have the "subtract 1" - it makes it

> harder to reason about. I'd also guess "3" and "4" are slowest.

>

> "1." can be simplified by hardcoding max....

> 5. (4294967295 bitShift: shift negated) bitShift: shift) asByteArray

>

> Additional alternative...

> 6. ((4294967295 bitShift: shift) rem: 4294967296) asByteArray

>

> And why not low-brow...

> 7. CIDRLookup at: cidr.

>

> cheers -ben

This also seems to work for IPV4:

(max << shift) asByteArray last: 4

Dave