# Finding largest netmask for given set of hosts

Edvard Majakari edvard.majakari at staselog.com
Fri Aug 9 07:23:47 EDT 2002

```I'm trying to construct a class method which returns the smallest possible
network (largest netmask) for given set of hosts.

Now, I have list of ip addresses in object variable self._list. Each IP
address is in binary format (32-bit long)

The algorithm is below:

nw = self._list[0]      # initialise network to first ip address
nm = 0xFFFFFFFFL        # initialise netmask to 255.255.255.255 (32)

# for every other ip in the list
for ip in self._list[1:]:
nw = nw & nm  # AND network with netmask

# XOR the network with ip address. All differing bits
# should be ones after XOR, and all bits that are same should
# be ones

x = nw ^ ip

# now, if nw was 192.128.11.12 and first ip was 192.128.11.20,
# result of x should be 24L, which is corresponds to bitmask of
# 00000000000000000000000000011000. However, this is
# undesirable - we need a bitmask that has ones for the
# constant parts of the ip addresses and zeroes for the rest.
# by inverting x (~ x) we get
# 11111111111111111111111111100111, which still contains
# one at the end of the bitstring. We get rid of this bit
# by calling a function that zeroes all the rest bits after
# the first zero bit:

nm = zero_after_first_zero(dec2bin(~x))

# now nm (according to the example) is
# 11111111111111111111111111100000. We use this to
# to recalculate new network:
nw = nw & nm

# now nw should be 192.128.11.0 and netmask is 27

return nw

The problem is that in Python, it seems quite difficult to create a
routine dec2bin that would handle binary digits. I also doubt the
algorithm is the best for this kind of thing.

I wonder is there any existing Python modules that would do this kind of
thing? I searched one for days (using Google), but didn't find any..

--
# Edvard Majakari		Software Engineer
# PGP PUBLIC KEY available    	Soli deo gloria - Glory to God alone!

\$_ = '456476617264204d616a616b6172692c20612043687269737469616e20'; print
join('',map{chr hex}(split/(\w{2})/)),uc substr(crypt(60281449,'es'),2,4),"\n";

```