On Sun, Dec 16, 2007 at 06:07:24PM +1000, Anthony Towns wrote: > Ah, like that. Attached. > $ ./rule9-prediction.py ftp.us.debian.org
No, really. Cheers, aj
#!/usr/bin/env python
import socket, sys
def ip2bits(ip):
return "".join(
[ "".join(
[ ("%d" % (int(x*(2**-y)) % 2)) for y in range(7,-1,-1) ] )
for x in [ int(x,10) for x in ip.split(".") ] ] )
def bits2ip(bits):
return ".".join([ "%03d" % (int(bits[x*8:x*8+8],2)) for x in range(4) ])
def iprange(prefix):
lo = bits2ip( (prefix + "0"*32)[:32] )
hi = bits2ip( (prefix + "1"*32)[:32] )
if hi == "255.255.255.255":
nx = ""
else:
nx = bits2ip( (prefix[:prefix.rfind("0")] + "1" + "0" * 31)[:32] )
return (lo, hi, nx)
ips = []
for arg in sys.argv[1:]:
ips.extend( [ (x[4][0], ip2bits(x[4][0]))
for x in socket.getaddrinfo(arg, "http") ] )
ips.sort( lambda x,y: cmp(x[1], y[1]) )
if ips == []:
print "Usage: %s host|address host|address..." % sys.argv[0]
sys.exit(1)
working = [ ("", [b for ip,b in ips]) ]
result = []
while len(working) > 0:
newworking = []
for (prefix, ips) in working:
if len(ips) == 1:
result.append( (prefix, ips) )
continue
prefixL = prefix + "0"
prefixR = prefix + "1"
ipsL = []
ipsR = []
for ip in ips:
if ip.startswith(prefixL):
ipsL.append(ip)
else:
ipsR.append(ip)
if ipsL == []:
result.append( (prefixL, ips) )
else:
newworking.append( (prefixL, ipsL) )
if ipsR == []:
result.append( (prefixR, ips) )
else:
newworking.append( (prefixR, ipsR) )
working = newworking
result.sort(lambda x,y: cmp(x[0], y[0]))
prefix, ips = result[0]
lo, hi, nx = iprange(prefix)
for p2, ips2 in result[1:]:
l2, h2, n2 = iprange(p2)
if nx != l2:
print "OUT OF ORDER"
sys.exit(1)
if ips != ips2:
print "%15s-%15s: %s" % (lo, hi, ", ".join([bits2ip(b) for b in ips]))
lo, hi, nx, ips = l2, h2, n2, ips2
else:
hi, nx = h2, n2
print "%15s-%15s: %s" % (lo, hi, ", ".join([bits2ip(b) for b in ips]))
signature.asc
Description: Digital signature

