简体   繁体   中英

How to loop through an IP range?

What's the easiest way to loop through an IP range in python? I saw a couple of examples but none of them worked for me. I tried the following technique, works perfectly, but it will not exit the loop when it reaches the end of the range. For example, I will specify the following arguments via the command line

python loop.py 1.0.0.0 2.0.0.0 

and the loop will not stop execution when the range reaches 2.0.0.0

start_ip = string.split(sys.argv[1], ".")
end_ip = string.split(sys.argv[2], ".")

for c1 in range(int(start_ip[0]), 255):
    for c2 in range(int(start_ip[1]), 255):
        for c3 in range(int(start_ip[2]), 255):
            for c4 in range(int(start_ip[3]), 255):
                if "%d.%d.%d.%d" % (c1, c2, c3, c4) == "%d.%d.%d.%d" % (int(end_ip[0]), int(end_ip[1]), int(end_ip[2]), int(end_ip[3])):
                    break
                else:
                    print "%d.%d.%d.%d" % (c1, c2, c3, c4)

It would be great if someone could tell me why my code isn't working correctly, or show me a better way to iterate through an IP range, thanks. All help is appreciated.

Your looping logic is wrong. At the if statement where you do the comparison with the upper bound of the IP address, the break statement only breaks the immediate loop above the if statement.

Therefore it continues to run for the whole range. You need to break from each of the for loops. Something like this :

done = False

for c1 in range(int(start_ip[0]), 255):
    for c2 in range(int(start_ip[1]), 255):
        for c3 in range(int(start_ip[2]), 255):
            for c4 in range(int(start_ip[3]), 255):
                if "%d.%d.%d.%d" % (c1, c2, c3, c4) == "%d.%d.%d.%d" % (int(end_ip[0]), int(end_ip[1]), int(end_ip[2]), int(end_ip[3])):
                    done = True
                    break
                else:
                    print "%d.%d.%d.%d" % (c1, c2, c3, c4)
            if(done):
                break
        if(done):
            break
    if(done):
        break

As an IP is just 4 bytes, it can be expressed as a single 32-bit integer. That way, if we can transform from and to this integer, we only need one loop:

# How much is each byte 'worth' in the ip?
units = [1 << (8 * i) for i in range(3, -1, -1)]


def ip_to_int(ip):
    return sum(int(byte) * unit for (byte, unit) in zip(ip.split('.'), units))


def int_to_ip(i):
    return '.'.join(str((i / bit) & 0xff) for bit in units)

#----------------------
start_ip = "1.0.0.0"
end_ip = "2.0.0.0"

ips = (int_to_ip(i) for i in xrange(ip_to_int(start_ip), ip_to_int(end_ip)))
for ip in ips:
    print ip

This makes the looping really easy, and also gives you easy ways to see if one IP is bigger than another or equal to it (just compare the ints).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM