Python Sub-net Calculator Example

In this article we produce a simple algorithm for calculating sub-net ranges for any ip / subnet set!

Python Sub-net Calculator Example

If you are looking for a good simple sub-net calculator here is a working code example that will return the sub-net range of any ip / sub-net combination:

 class ip_domains():
    
    def n_round(self, n, base=2):
        a =  base * round(n / base)
        return a
    def generate_random_ip(self):
        a = random.randint(0, 255)
        b = random.randint(0, 255)
        c = random.randint(0, 255)
        d = random.randint(0, 255)
        return f'{a}.{b}.{c}.{d}'
    def calculate_subnets(self, ip, offset, base=2):
        end_ip = int(ip[offset])
        aval = self.n_round(end_ip, base)
        bval = aval + base - 1
        done = False
        if end_ip < aval:
            aval -= base
            bval -= base
            done = True
        if end_ip > bval and not done:
            aval += base
            bval += base
        a_ip = ip
        b_ip = ip.copy()
        a_ip[offset] = str(aval)
        b_ip[offset] = str(bval)
        if offset < -1:
            if offset == -2:
                a_ip[-1] = '0'
                b_ip[-1] = '255'
            if offset == -3:
                a_ip[-2] = '0'
                a_ip[-1] = '0'
                b_ip[-2] = '255'
                b_ip[-1] = '255'
        return [a_ip, b_ip]
    def ip_cidr_decode(self, ip, inetmask):
        inetmask = int(inetmask)
        split_ip = ip.split('.')
        #region Subnet 32 / 255.255.255.255
        if inetmask == 32:
            print("Subnet Mask: 255.255.255.255")
            return [ip, ip, '255.255.255.255']
        #endregion
        #region Subnet 31 / 255.255.255.254
        if inetmask == 31:
            mset = self.calculate_subnets(split_ip, -1, 2)
            return [mset[0], mset[1], '255.255.255.254']
        #endregion
        #region Subnet 30 / 255.255.255.252
        if inetmask == 30:
            mset = self.calculate_subnets(split_ip, -1, 4)
            return [mset[0], mset[1], '255.255.255.252']
        #endregion
        #region Subnet 29 / 255.255.255.248
        if inetmask == 29:
            mset = self.calculate_subnets(split_ip, -1, 8)
            return [mset[0], mset[1], '255.255.255.248']
        #endregion
        #region Subnet 28 / 255.255.255.240
        if inetmask == 28:
            mset = self.calculate_subnets(split_ip, -1, 16)
            return [mset[0], mset[1], '255.255.255.240']
        #endregion
        #region Subnet 27 / 255.255.255.224
        if inetmask == 27:
            mset = self.calculate_subnets(split_ip, -1, 32)
            return [mset[0], mset[1], '255.255.255.224']
        #endregion
        #region Subnet 26 / 255.255.255.192
        if inetmask == 26:
            mset = self.calculate_subnets(split_ip, -1, 64)
            return [mset[0], mset[1], '255.255.255.192']
        #endregion
        #region Subnet 25 / 255.255.255.128
        if inetmask == 25:
            mset = self.calculate_subnets(split_ip, -1, 128)
            return [mset[0], mset[1], '255.255.255.128']
        #endregion
        #region Subnet 24 / 255.255.255.0
        if inetmask == 24:
            mset = self.calculate_subnets(split_ip, -1, 256)
            return [mset[0], mset[1], '255.255.255.0']
        #endregion
        #region Subnet 23 / 255.255.254.0
        if inetmask == 23:
            mset = self.calculate_subnets(split_ip, -2, 2)
            return [mset[0], mset[1], '255.255.254.0']
        #endregion
        #region Subnet 22 / 255.255.252.0
        if inetmask == 22:
            mset = self.calculate_subnets(split_ip, -2, 4)
            return [mset[0], mset[1], '255.255.252.0']
        #endregion
        #region Subnet 21 / 255.255.248.0
        if inetmask == 21:
            mset = self.calculate_subnets(split_ip, -2, 8)
            return [mset[0], mset[1], '255.255.248.0']
        #endregion
        #region Subnet 20 / 255.255.240.0
        if inetmask == 20:
            mset = self.calculate_subnets(split_ip, -2, 16)
            return [mset[0], mset[1], '255.255.240.0']
        #endregion
        #region Subnet 19 / 255.255.224.0
        if inetmask == 19:
            mset = self.calculate_subnets(split_ip, -2, 32)
            return [mset[0], mset[1], '255.255.224.0']
        #endregion
        #region Subnet 18 / 255.255.192.0
        if inetmask == 18:
            mset = self.calculate_subnets(split_ip, -2, 64 )
            return [mset[0], mset[1], '255.255.192.0']
        #endregion
        #region Subnet 17 / 255.255.128.0
        if inetmask == 17:
            mset = self.calculate_subnets(split_ip, -2, 128)
            return [mset[0], mset[1], '255.255.128.0']
        #endregion
        #region Subnet 16 / 255.255.0.0.
        if inetmask == 16:
            mset = self.calculate_subnets(split_ip, -2, 256)
            return [mset[0], mset[1], '255.255.0.0']
        #endregion
        #region Subnet 15 / 255.254.0.0
        if inetmask == 15:
            mset = self.calculate_subnets(split_ip, -3, 2)
            return [mset[0], mset[1], '255.254.0.0']
        #endregion
        #region Subnet 14 / 255.252.0.0
        if inetmask == 14:
            mset = self.calculate_subnets(split_ip, -3, 4)
            return [mset[0], mset[1], '255.252.0.0']
        #endregion
        #region Subnet 13 / 255.248.0.0
        if inetmask == 13:
            mset = self.calculate_subnets(split_ip, -3, 8)
            return [mset[0], mset[1], '255.248.0.0']
        #endregion
        #region Subnet 12 / 255.240.0.0
        if inetmask == 12:
            mset = self.calculate_subnets(split_ip, -3, 16)
            return [mset[0], mset[1], '255.240.0.0']
        #endregion
        #region Subnet 11 / 255.224.0.0
        if inetmask == 11:
            mset = self.calculate_subnets(split_ip, -3, 32)
            return [mset[0], mset[1], '255.224.0.0']
        #endregion
        #region Subnet 10 / 255.192.0.0
        if inetmask == 10:
            mset = self.calculate_subnets(split_ip, -3, 64)
            return [mset[0], mset[1], '255.192.0.0.']
        #endregion
        #region Subnet 9 / 255.128.0.0
        if inetmask == 9:
            mset = self.calculate_subnets(split_ip, -3, 128)
            return [mset[0], mset[1], '255.128.0.0']
        #endregion
        #region Subnet 8 / 255.0.0.0
        if inetmask == 8:
            mset = self.calculate_subnets(split_ip, -3, 256)
            return [mset[0], mset[1], '255.0.0.0']
        #endregion
        
ip_testing = ipdomains()

for x in range(20):
    random_ip = ip_testing.generate_random_ip()
    x = 30
    ip_domain = random_ip
    while x >= 8:
        mval = ip_testing.ip_cidr_decode(ip_domain, x)
        print(f"{ip_domain} -- {mval}")
        x -= 1

You can see the output ranges are valid sub-nets.

65.205.193.72--[['65','205','193','72'],['65','205','193','75'],'255.255.255.252']
65.205.193.72--[['65','205','193','72'],['65','205','193','79'],'255.255.255.248']
65.205.193.72--[['65','205','193','64'],['65','205','193','79'],'255.255.255.240']
65.205.193.72--[['65','205','193','64'],['65','205','193','95'],'255.255.255.224']
65.205.193.72--[['65','205','193','64'],['65','205','193','127'],'255.255.255.192']
65.205.193.72--[['65','205','193','0'],['65','205','193','127'],'255.255.255.128']
65.205.193.72--[['65','205','193','0'],['65','205','193','255'],'255.255.255.0']
65.205.193.72--[['65','205','192','0'],['65','205','193','255'],'255.255.254.0']
65.205.193.72--[['65','205','192','0'],['65','205','195','255'],'255.255.252.0']
65.205.193.72--[['65','205','192','0'],['65','205','199','255'],'255.255.248.0']
65.205.193.72--[['65','205','192','0'],['65','205','207','255'],'255.255.240.0']
65.205.193.72--[['65','205','192','0'],['65','205','223','255'],'255.255.224.0']
65.205.193.72--[['65','205','192','0'],['65','205','255','255'],'255.255.192.0']
65.205.193.72--[['65','205','128','0'],['65','205','255','255'],'255.255.128.0']
65.205.193.72--[['65','205','0','0'],['65','205','255','255'],'255.255.0.0']
65.205.193.72--[['65','204','0','0'],['65','205','255','255'],'255.254.0.0']
65.205.193.72--[['65','204','0','0'],['65','207','255','255'],'255.252.0.0']
65.205.193.72--[['65','200','0','0'],['65','207','255','255'],'255.248.0.0']
65.205.193.72--[['65','192','0','0'],['65','207','255','255'],'255.240.0.0']
65.205.193.72--[['65','192','0','0'],['65','223','255','255'],'255.224.0.0']
65.205.193.72--[['65','192','0','0'],['65','255','255','255'],'255.192.0.0.']
65.205.193.72--[['65','128','0','0'],['65','255','255','255'],'255.128.0.0']
65.205.193.72--[['65','0','0','0'],['65','255','255','255'],'255.0.0.0']
182.216.236.115--[['182','216','236','112'],['182','216','236','115'],'255.255.255.252']
182.216.236.115--[['182','216','236','112'],['182','216','236','119'],'255.255.255.248']
182.216.236.115--[['182','216','236','112'],['182','216','236','127'],'255.255.255.240']
182.216.236.115--[['182','216','236','96'],['182','216','236','127'],'255.255.255.224']
182.216.236.115--[['182','216','236','64'],['182','216','236','127'],'255.255.255.192']
182.216.236.115--[['182','216','236','0'],['182','216','236','127'],'255.255.255.128']
182.216.236.115--[['182','216','236','0'],['182','216','236','255'],'255.255.255.0']
182.216.236.115--[['182','216','236','0'],['182','216','237','255'],'255.255.254.0']
182.216.236.115--[['182','216','236','0'],['182','216','239','255'],'255.255.252.0']
182.216.236.115--[['182','216','232','0'],['182','216','239','255'],'255.255.248.0']
182.216.236.115--[['182','216','224','0'],['182','216','239','255'],'255.255.240.0']
182.216.236.115--[['182','216','224','0'],['182','216','255','255'],'255.255.224.0']
182.216.236.115--[['182','216','192','0'],['182','216','255','255'],'255.255.192.0']
182.216.236.115--[['182','216','128','0'],['182','216','255','255'],'255.255.128.0']
Linux Rocks Every Day