Skip to content

Instantly share code, notes, and snippets.

@lewisxy
Created December 24, 2019 05:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lewisxy/1be90b901492656f3c424443350ad98b to your computer and use it in GitHub Desktop.
Save lewisxy/1be90b901492656f3c424443350ad98b to your computer and use it in GitHub Desktop.
select random IP from a specified range
#!/bin/python3
import json
import random
example_data = """
[
{
"type": "range",
"name": "myRange",
"range_begin": "1.2.3.4",
"range_end": "1.2.3.5"
},
{
"type": "list",
"name": "local gateway",
"list_data": [
"192.168.1.1",
"192.169.2.2"
]
},
{
"type": "cidr",
"name": "myCidr",
"cidr_data": "123.234.0.0/31"
}
]
"""
# goal: given a list of ips, in above format, return a random ip
# idea: parse json, create a list of IpRange objects
# then compute the total number of ips
# find a random numnber within this range,
# then convert the index into a value of a specific index of an object
# call object.find(index) to return
def ip_to_int(ip):
try:
a, b, c, d = ip.split(".")
a = int(a)
b = int(b)
c = int(c)
d = int(d)
assert(a >= 0 and a <= 255)
assert(b >= 0 and b <= 255)
assert(c >= 0 and c <= 255)
assert(d >= 0 and d <= 255)
return ((a & 0xff) << 24) + ((b & 0xff) << 16) + ((c & 0xff) << 8) + (d & 0xff)
except: # Exception as e:
#print(e)
print("{} is not a valid IP".format(ip))
return None
def int_to_ip(n):
try:
a = (n >> 24) & 0xff
b = (n >> 16) & 0xff
c = (n >> 8) & 0xff
d = n & 0xff
return ".".join([str(a), str(b), str(c), str(d)])
except: #Exception as e:
#print(e)
print("{} is not a valid int for IP".format(n))
return None
# a = ip_to_int("255.255.255.0")
# print(a)
# print(int_to_ip(a))
# prototype functions for closure
def proto_find_list(lst):
l = len(lst)
def f(i):
if (i >= l or i < 0):
print("Out of Bound")
return None
else:
return lst[i]
return (l, f)
def proto_find_range(begin, end):
begin_num = ip_to_int(begin)
end_num = ip_to_int(end)
l = end_num - begin_num + 1
if (l < 0):
print("Invalid Range")
return None
def f(i):
if (i >= l or i < 0):
print("Out of Bound")
return None
else:
return int_to_ip(begin_num + i)
return (l, f)
def proto_find_cidr(cidr):
try:
ip, bitlen = cidr.split("/")
bitlen = int(bitlen)
assert(bitlen <= 32 and bitlen >= 0)
remainlen = 32 - bitlen
l = (1 << remainlen)
base = (ip_to_int(ip) >> remainlen) << remainlen
except: #Exception as e:
#print(e)
print("{} is not a valid CIDR")
return None
def f(i):
if (i >= l or i < 0):
print("Out of Bound")
return None
else:
return int_to_ip(base + i)
return (l, f)
class IpRange:
def __init__(self, entry):
self.name = entry["name"] # str: name of list
entry_type = entry["type"]
if (entry_type == "range"):
self.size, self.find = proto_find_range(entry["range_begin"], entry["range_end"])
elif (entry_type == "list"):
self.size, self.find = proto_find_list(entry["list_data"])
elif (entry_type == "cidr"):
self.size, self.find = proto_find_cidr(entry["cidr_data"])
else:
print("Invalid type: {}".format(entry_type))
def build_list(entrylist):
res = [IpRange(x) for x in entrylist]
count = 0
for x in res:
count += x.size
return (count, res)
def randIP(lst, size):
num = random.randint(0, size - 1)
for x in lst:
if num < x.size:
return x.find(num)
else:
num -= x.size
if __name__ == "__main__":
# filename = "filename.json"
# with open(filename, "rb") as f:
# data = json.loads(f.read())
data = json.loads(example_data)
count, res = build_list(data)
print("{} IPs loaded".format(count))
for _ in range(10):
print(randIP(res, count))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment