Question

Can anyone think of an algorithm to put all of the addresses between two others and put them in a list (using python)? For example:

findIPs('111.111.111.0', '111.111.111.3')

Should return ('111.111.111.0', '111.111.111.1', '111.111.111.2', '111.111.111.3'). My main problem arises from when corresponding blocks are identical otherwise I could just use nested for loops with the range function.

Was it helpful?

Solution

Python 3.3 with standard library ipaddress module / Python 3.2-, Python 2.x with ipaddr

try:
    from ipaddress import ip_address
except ImportError:
    from ipaddr import IPAddress as ip_address

def findIPs(start, end):
    start = ip_address(start)
    end = ip_address(end)
    result = []
    while start <= end:
        result.append(str(start))
        start += 1
    return result

print(findIPs('111.111.111.0', '111.111.111.3'))

Python 3.2-, Python 2.x

import struct
import socket

def findIPs(start, end):
    ipstruct = struct.Struct('>I')
    start, = ipstruct.unpack(socket.inet_aton(start))
    end, = ipstruct.unpack(socket.inet_aton(end))
    return [socket.inet_ntoa(ipstruct.pack(i)) for i in range(start, end+1)]

print(findIPs('111.111.111.0', '111.111.111.3'))

OTHER TIPS

Here is one pretty straightforward approach:

def ip_to_int(ip):
    val = 0
    for i, s in enumerate(ip.split('.')):
        val += int(s) * 256 ** (3 - i)
    return val

def int_to_ip(val):
    octets = []
    for i in range(4):
        octets.append(str(val % 256))
        val = val >> 8
    return '.'.join(reversed(octets))

def findIPs(start, end):
    for i in range(ip_to_int(start), ip_to_int(end) + 1):
        yield int_to_ip(i)

Examples:

>>> list(findIPs('111.111.111.0', '111.111.111.3'))
['111.111.111.0', '111.111.111.1', '111.111.111.2', '111.111.111.3']
>>> list(findIPs('111.111.111.254', '111.111.112.1'))
['111.111.111.254', '111.111.111.255', '111.111.112.0', '111.111.112.1']

A little searching would have probably found the answer as well, but this should work:

import socket
import struct

ip_to_number = lambda ip: struct.unpack('!I', socket.inet_aton(ip))[0]
number_to_ip = lambda num: socket.inet_ntoa(struct.pack('!I', num))

def ip_range(a, b):
    a = ip_to_number(a)
    b = ip_to_number(b)

   for i in range(a, b+1):
     yield number_to_ip(i)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top