Last active
April 16, 2020 00:24
-
-
Save M1nified/21a64e9bea0516c4aaaa11467a8472e1 to your computer and use it in GitHub Desktop.
Subnetwork calculator
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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