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]))
Attachment:
signature.asc
Description: Digital signature