Skip to content

Instantly share code, notes, and snippets.

@M1nified
Last active April 16, 2020 00:24
Show Gist options
  • Save M1nified/21a64e9bea0516c4aaaa11467a8472e1 to your computer and use it in GitHub Desktop.
Save M1nified/21a64e9bea0516c4aaaa11467a8472e1 to your computer and use it in GitHub Desktop.
Subnetwork calculator
import re, functools
RE_RAW_ADDR='^(\d{1,3}\.){3}\d{1,3}\/\d{1,2}$'
RE_RAW_SPLIT='\.|\/'
def is_raw_addr(raw_addr):
if re.fullmatch(RE_RAW_ADDR, raw_addr) is None:
return False
split = split_raw_addr(raw_addr)
octs = split[:4]
mask = split[4]
if all([lambda x: x<=255 and x >= 0 for _ in octs]) is not True:
return False
if mask < 0 or mask > 32:
return False
return True
def split_raw_addr(raw_addr):
return [int(s) for s in re.split(RE_RAW_SPLIT, raw_addr) if s.isdigit()]
def addr_bin_arr_to_str(bin_arr):
strs = [str(x) for x in bin_arr]
return '.'.join([''.join(strs[x*8:x*8+8]) for x in range(0,4)])
def addr_dec_arr_to_str(dec_arr):
return '.'.join([str(x) for x in dec_arr])
def addr_bin_arr_to_dec_arr(bin_arr):
strs = [str(x) for x in bin_arr]
bin_octs = [''.join(strs[x*8:x*8+8]) for x in range(0,4)]
dec_octs = [int(x, 2) for x in bin_octs]
return dec_octs
#!/usr/bin/python3
# Example execution
# ./netcalc.py 191.42.5.1/21
import sys
import addrfuncs as afs
import json
class NotAnAddressException(Exception):
pass
class Address:
def __init__(self, octs_dec, mask_dec):
self.addr_dec = octs_dec
self.mask_short = mask_dec
# self.mask_bin = [1 for _ in range(0,mask_dec)] + [0 for _ in range(0, 32 - mask_dec)]
self.mask_bin = [int(s) for s in ''.rjust(self.mask_short, '1').ljust(32, '0')]
self.mask_dec = afs.addr_bin_arr_to_dec_arr(self.mask_bin)
self.addr_bin = [int(s) for s in ''.join([bin(oct).replace('0b', '').rjust(8, '0') for oct in self.addr_dec])]
pass
def calcNetworkAddress(self):
self.network_bin = [ a if m == 1 else 0 for (a, m) in zip(self.addr_bin, self.mask_bin)]
self.network_dec = afs.addr_bin_arr_to_dec_arr(self.network_bin)
pass
def calcHostMaskAndLimits(self):
self.host_mask_bin = [0 if x == 1 else 1 for x in self.mask_bin]
self.host_mask_dec = afs.addr_bin_arr_to_dec_arr(self.host_mask_bin)
self.host_min_bin = self.network_bin
self.host_min_bin[31] = 1
self.host_min_dec = afs.addr_bin_arr_to_dec_arr(self.host_min_bin)
self.host_max_bin = [ n if m == 0 else 1 for (n, m) in zip(self.network_bin, self.host_mask_bin)]
self.host_max_bin[31] = 0
self.host_max_dec = afs.addr_bin_arr_to_dec_arr(self.host_max_bin)
self.max_host_count = 2**(32 - self.mask_short) - 2
def calcBroadcastAddress(self):
self.broadcast_bin = [ n if m == 0 else 1 for (n, m) in zip(self.network_bin, self.host_mask_bin)]
self.broadcast_dec = afs.addr_bin_arr_to_dec_arr(self.broadcast_bin)
def calcAddressClass(self):
fstb = self.addr_bin[:5]
class_idx = 0
for bit in fstb:
if bit == 0:
break
class_idx += 1
self.addr_class = [
'Class A (0-127)',
'Class B (128-191)',
'Class C (192-223)',
'Class D (224-239)',
'Class E (240-255)'
][class_idx]
def getHumanizedData(self):
data = {
'raw': afs.addr_dec_arr_to_str(self.addr_dec) + '/' + str(self.mask_short),
'class': self.addr_class,
'addr_dec': afs.addr_dec_arr_to_str(self.addr_dec),
'mask_dec': afs.addr_dec_arr_to_str(self.mask_dec),
'network_dec': afs.addr_dec_arr_to_str(self.network_dec),
'addr_bin': afs.addr_bin_arr_to_str(self.addr_bin),
'mask_bin': afs.addr_bin_arr_to_str(self.mask_bin),
'network_bin': afs.addr_bin_arr_to_str(self.network_bin),
'broadcast_bin': afs.addr_bin_arr_to_str(self.broadcast_bin),
'broadcast_dec': afs.addr_dec_arr_to_str(self.broadcast_dec),
'host_mask_bin': afs.addr_bin_arr_to_str(self.host_mask_bin),
'host_min_bin': afs.addr_bin_arr_to_str(self.host_min_bin),
'host_max_bin': afs.addr_bin_arr_to_str(self.host_max_bin),
'host_mask_dec': afs.addr_dec_arr_to_str(self.host_mask_dec),
'host_min_dec': afs.addr_dec_arr_to_str(self.host_min_dec),
'host_max_dec': afs.addr_dec_arr_to_str(self.host_max_dec),
'max_host_count': self.max_host_count,
}
return data
def print(self):
data = self.getHumanizedData()
def left_col(txt):
return txt.ljust(17, ' ')
print(left_col('Full address:'), data['raw'])
print()
print(left_col('This address is:'), data['class'])
print()
print(left_col('Address DEC:'), data['addr_dec'])
print(left_col('Mask DEC:'), data['mask_dec'])
print(left_col('Network DEC:'), data['network_dec'])
print()
print(left_col('Address BIN:'), data['addr_bin'])
print(left_col('Mask BIN:'), data['mask_bin'])
print(left_col('Network BIN:'), data['network_bin'])
print()
print(left_col('Broadcast BIN:'), data['broadcast_bin'])
print(left_col('Broadcast DEC:'), data['broadcast_dec'])
print()
print(left_col('Host mask BIN:'), data['host_mask_bin'])
print(left_col('Host min BIN:'), data['host_min_bin'])
print(left_col('Host max BIN:'), data['host_max_bin'])
print()
print(left_col('Host mask DEC:'), data['host_mask_dec'])
print(left_col('Host min DEC:'), data['host_min_dec'])
print(left_col('Host max DEC:'), data['host_max_dec'])
print()
print(left_col('Max hosts count:'), data['max_host_count'])
print()
def toJson(self):
with open('ip.json', 'w') as file:
json.dump(self.getHumanizedData(), file, indent=4)
@classmethod
def try_parse(cls, raw_addr):
if afs.is_raw_addr(raw_addr) == False:
raise NotAnAddressException()
parts = afs.split_raw_addr(raw_addr)
octs = parts[:4]
mask = parts[4]
return cls(octs, mask)
raw_addr = sys.argv[1]
addr = Address.try_parse(raw_addr)
addr.calcNetworkAddress()
addr.calcHostMaskAndLimits()
addr.calcBroadcastAddress()
addr.calcAddressClass()
addr.toJson()
addr.print()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment