Skip to content
Advertisement

Generate Range of IPs in Python [closed]

If I enter IP “127“: I want to generate everything from 127.0.0.1 to 127.255.255.255


If I enter IP “127.0” I want to generate everything from 127.0.0.1 to 127.0.255.255


If I enter IP “127.0.0” I want to generate everything from 127.0.0.1 to 127.0.0.255


Using netaddr

Advertisement

Answer

The original question was based on bash.. if you just want the pure python implementation, scroll down:

I think your specific problem can probably be solved in bash with some pain, but here’s a stab at the general problem:

So, first of all it’s probably worth noting that not all the IP addresses in a particular range are valid host addresses. Specifically, the first and last addresses are reserved in IPv4 (network/broadcast).

Secondly, an IPv4 address, say 192.168.0.1, is really just a 32-bit/4-byte number that’s split into 4 chunks of 8-bit/1-byte each. You don’t have place the network/host portion split of the address on an 8-bit boundary though. 127.0.0.0/24 for example places the split at the third dot (24 bits in) and contains host addresses 127.0.0.1-254, but you can equally well split it 28 bits in, e.g. 127.0.0.0/28, which would contain hosts 127.0.0.1-14.

Thirdly, the “correct” way (I believe) to generate the data you are asking for, is by converting the IP address into binary, e.g. 127.0.0.1 = 01111111000000000000000000000001, determine where your host/network split is (say it’s a /28), fix the first 28 bits, and then count up the binary number and then convert back to the dotted decimal representation if required:

01111111000000000000000000000001 = .1
---------fixed--------------**** ** variable

so you get:
01111111000000000000000000000010 = .2
01111111000000000000000000000011 = .3

etc.

Doing this in bash is of course a pain.

Now, if you have Python3 available, you can use the ipaddress module to generate all the valid host addresses on a given network (see below).

>>> import ipaddress
>>> print("n".join([str(x) for x in ipaddress.ip_network("192.0.2.0/28").hosts()]))
192.0.2.1
192.0.2.2
192.0.2.3
192.0.2.4
192.0.2.5
192.0.2.6
192.0.2.7
192.0.2.8
192.0.2.9
192.0.2.10
192.0.2.11
192.0.2.12
192.0.2.13
192.0.2.14

This module also supports IPv6 incidentally, so you can generate the hosts of 2001:0db8::/120 using ipaddress.ip_network("2001:0db8::/120").hosts().

You can (though you don’t have to) wrap this in a shell-script-compatible one-liner..

python3 -c 'import ipaddress; print("n".join([str(x) for x in ipaddress.ip_network("192.0.2.0/28").hosts()]))'

Now, all you need to is

#!/bin/bash
# split it up
IFS='.' read -a array <<< "127.0.0"
#echo ${array[*]}
#127 0 0

mask=$(( ${#array[@]} * 8))
# 28

# add missing 0s.
for $i in {1..4}; do
   if [ i -gt ${#array[@]} ]; then
      array[i]="0"
   fi
done
#echo ${array[*]}
#127 0 0 0


# join, see http://stackoverflow.com/questions/1527049/bash-join-elements-of-an-array
SAVE_IFS=$IFS
IFS="."
full_ip="${array[*]}"
IFS=$SAVE_IFS
# 127.0.0.0

# now add /mask
network="$full_ip/$mask"
# 127.0.0.0/24

python3 -c "import ipaddress; print("\n".join([str(x) for x in ipaddress.ip_network("$network").hosts()]))"
#127.0.0.1
#127.0.0.2
# ...
#127.0.0.254

Pure Python3:

import ipaddress
input="127.0.0"
input_arr=input.split(".") # ['127', '0', '0']
netmask=len(input_arr)*8  # 24
for i in range(len(input_arr), 4):
     input_arr.append('0')
# input_arr = ['127', '0', '0', '0']
ip='.'.join(input_arr)  # '127.0.0.0'
network=ip + '/' + str(netmask)  # '127.0.0.0/24'
print("n".join([str(x) for x in ipaddress.ip_network(network).hosts()]))

If you want to add the network/broadcast, just print the .network_address and .broadcast_address in addition.

User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement