Random IP Address Generator randip.py

I know there are probably better, easier ways to do this.
It was just a bit of a learning exercise for the sake of familiarising myself with Python.

It takes a single argument (positional parameter):
Either a 4 (IPv4) or a 6 (IPv6).  



Usage:

./randip.py 4
61.104.170.242

./randip.py 6
4bfc:391d:3ec8:68ef:0ec8:529b:166d:2ece




Code:

#!/usr/bin/env python3

from sys import argv

from random import randint, choice
from string import hexdigits

def random_ip(v):

    if v == 4:
        octets = []
        for x in range(4):
            octets.append(str(randint(0,255)))
        return '.'.join(octets)

    elif v == 6:
        octets = []
        for x in range(8):
            octet = []
            for x in range(4):
                octet.append(str(choice(hexdigits.lower())))
            octets.append(''.join(octet))
        return ':'.join(octets)

    else:
       return 

def main(): 
    print(random_ip(int(argv[1])))

if __name__ == '__main__':
    main()
Python is often described as a "batteries included" kind of language, and this is no exception.

There's a module just for IP address manipulation and another module to generate random numbers. Put together, they do exactly what you want, in a way that's slightly more readable (IMO).

For this example, I'll assume that the variable v contains either 4 or 6.

from random import getrandbits
from ipaddress import IPv4Address, IPv6Address

if v == 4:
    bits = getrandbits(32) # generates an integer with 32 random bits
    addr = IPv4Address(bits) # instances an IPv4Address object from those bits
    addr_str = str(addr) # get the IPv4Address object's string representation
elif v == 6:
    bits = getrandbits(128) # generates an integer with 128 random bits
    addr = IPv6Address(bits) # instances an IPv6Address object from those bits
    # .compressed contains the short version of the IPv6 address
    # str(addr) always returns the short address
    # .exploded is the opposite of this, always returning the full address with all-zero groups and so on
    addr_str = addr.compressed 

print(addr_str)


Here, addr_str will hold a fully random IPv4 or IPv6 address.

You can even generate random addresses from a subnet like this:

from random import getrandbits
from ipaddress import IPv4Network, IPv4Address

# network containing all addresses from 10.0.0.0 to 10.0.0.255
subnet = IPv4Network("10.0.0.0/24") 

# subnet.max_prefixlen contains 32 for IPv4 subnets and 128 for IPv6 subnets
# subnet.prefixlen is 24 in this case, so we'll generate only 8 random bits
bits = getrandbits(subnet.max_prefixlen - subnet.prefixlen)

# here, we combine the subnet and the random bits
# to get an IP address from the previously specified subnet
addr = IPv4Address(subnet.network_address + bits)
addr_str = str(addr)

print(addr_str)


Here, addr_str will always contain IP addresses like 10.0.0.184, 10.0.0.42 and so on. It works the same way with IPv6 addresses, except in that case you'd have to import IPv6Network and IPv6Address instead.