How can I find the closest match using python netaddr for same prefixlength?
>>> l = ['172.27.145.130/25', '172.27.145.129/25', '172.27.145.131/25']
>>> myip = '172.27.145.129'
>>> netaddr.IPAddress(myip) in netaddr.IPNetwork(l[0])
True
>>> netaddr.IPAddress(myip) in netaddr.IPNetwork(l[1])
True
>>> netaddr.IPAddress(myip) in netaddr.IPNetwork(l[2])
True
>>>
You seem to be missing a key point here: You say that "all the three ip subnets are part of the same network 172.27.145.128/25", but that's not true; all of them are that same network, just different nonstandard names for it. That's the way IP networking works: for an N-bit network, the last N bits of the base address don't matter. So there is no way to contrast them with each other and pick out which one is a "longest" or "closest" or any other kind of match, because they will all be exactly the same match.
It's possible that you mean these to be interfaces, not networks. An interface has an address within a network—for example, address
172.27.145.130
in network172.27.145.128/25
. And you can specify that with the shorthand127.27.145.130/25
. Yes, the shorthand form for interfaces looks the same as the shorthand form for networks, but they're not the same thing.If you still don't get the difference between addresses, networks, and interfaces, the 3.3+ Python docs have a great HOWTO.
While
netaddr
doesn't have any support for interfaces, the stdlib'sipaddress
and the third-partyipaddress
backport for Python 2.6-2.7, do. For example:So, maybe what you're asking is which interface shares the most bits in common with a given address? (I'm still not sure if this is what you mean by "closest match" or "longest match", but it seems like a reasonable guess.)
That's still an ambiguous question. You could either be asking which interface's address shares more bits period, or which one shares more bits within the subnet. But since they're all in the same subnet, that doesn't matter.
And that means that we can even use the
netaddr
network objects as ersatz interface objects (although really, you'd be better off usingipaddress
or another library that actually supports interface objects).So:
(Obviously you can merge together most of those steps so the whole thing is just two or three lines.)
And now we're just comparing strings.
But
netaddr.IPAddress
also has an&
operator, so we can make it even simpler:There are other ways to tackle this. For example, the
value
of eachIPAddress
is a 32-bit int, so you can just and those together and count the bits numerically instead of as a string. But hopefully this shows things explicitly.