Now we make script for subnet calculator. We will enter an IP address and subnet mask. If it's invalid program will check and ask again for a valid IP address and subnet mask.


Enter an IP address: 12.2.2.2

Enter a subnet mask: 255.255.255.0


Than program calculates network and broadcast address, number of valid hosts per subnet, wildcard mask and mask bit.

Network address is: 12.2.2.0

Broadcast address is: 12.2.2.255

Number of valid hosts per subnet: 254

Wildcard mask: 0.0.0.255

Mask bits: 24


Than program asks whether to create a random IP address.

Generate random IP address from this subnet? (y/n) y

Random IP address is: 12.2.2.67



import random
import sys

def subnet_calc():
    try:
        print("\n")

 

       # Checking IP address validity

        while True:
            ip_address = input("Enter an IP address: ")

            # Checking octets
            ip_octets = ip_address.split('.')

            if (len(ip_octets) == 4) and (1 <= int(ip_octets[0]) <= 223) and (int(ip_octets[0]) != 127) and (
                    int(ip_octets[0]) != 169 or int(ip_octets[1]) != 254) and (
                    0 <= int(ip_octets[1]) <= 255 and 0 <= int(ip_octets[2]) <= 255 and 0 <= int(ip_octets[3]) <= 255):
                break

            else:
                print("\nThe IP address is INVALID! Please retry!\n")
                continue

        masks = [255, 254, 252, 248, 240, 224, 192, 128, 0]

        # Checking Subnet Mask validity

        while True:
            subnet_mask = input("Enter a subnet mask: ")

            # Checking octets

            mask_octets = subnet_mask.split('.')

            if (len(mask_octets) == 4) and (int(mask_octets[0]) == 255) and (int(mask_octets[1]) in masks) and (
                    int(mask_octets[2]) in masks) and (int(mask_octets[3]) in masks) and (
                    int(mask_octets[0]) >= int(mask_octets[1]) >= int(mask_octets[2]) >= int(mask_octets[3])):
                break

            else:
                print("\nThe subnet mask is INVALID! Please retry!\n")
                continue

        # Application #1 - Part #2

        # Algorithm for subnet identification, based on IP and Subnet Mask

        # Convert mask to binary string

        mask_octets_binary = []

        for octet in mask_octets:
            binary_octet = bin(int(octet)).lstrip('0b')
            # print(binary_octet)

            mask_octets_binary.append(binary_octet.zfill(8))

        # print(mask_octets_binary)

        binary_mask = "".join(mask_octets_binary)

        # print(decimal_mask)

        # Example: for 255.255.255.0 => 11111111111111111111111100000000

        # Counting host bits in the mask and calculating number of hosts/subnet

        no_of_zeros = binary_mask.count("0")
        no_of_ones = 32 - no_of_zeros
        no_of_hosts = abs(2 ** no_of_zeros - 2)  # return a positive value for the /32 mask (all 255s)

        # print(no_of_zeros)

        # print(no_of_ones)

        # print(no_of_hosts)

        # Obtaining wildcard mask

        wildcard_octets = []

        for octet in mask_octets:
            wild_octet = 255 - int(octet)
            wildcard_octets.append(str(wild_octet))

        # print(wildcard_octets)

        wildcard_mask = ".".join(wildcard_octets)

        # print(wildcard_mask)

        # Application #1 - Part #3

        # Convert IP to binary string

        ip_octets_binary = []

        for octet in ip_octets:
            binary_octet = bin(int(octet)).lstrip('0b')
            # print(binary_octet)

            ip_octets_binary.append(binary_octet.zfill(8))

        # print(ip_octets_binary)

        # Example: for 192.168.10.1 =>

        binary_ip = "".join(ip_octets_binary)

        # print(binary_ip)

        # Example: for 192.168.2.100 => 11000000101010000000101000000001

        # Getting the network address and broadcast address from the binary strings obtained above

        network_address_binary = binary_ip[:(no_of_ones)] + "0" * no_of_zeros

        # print(network_address_binary)

        broadcast_address_binary = binary_ip[:(no_of_ones)] + "1" * no_of_zeros
       

        # print(broadcast_address_binary)

        # Converting everything back to decimal (readable format)

        net_ip_octets = []

        # range(0, 32, 8) means 0, 8, 16, 24

        for bit in range(0, 32, 8):
            net_ip_octet = network_address_binary[bit: bit + 8]
            net_ip_octets.append(net_ip_octet)

        # We will end up with 4 slices of the binary IP address: [0: 8], [8: 16], [16: 24] and [24:31]; remember that each slice goes up to, but not including, the index on the right side of the colon!

        # print(net_ip_octets)

        net_ip_address = []

        for each_octet in net_ip_octets:
            net_ip_address.append(str(int(each_octet, 2)))

        # print(net_ip_address)

        network_address = ".".join(net_ip_address)

        # print(network_address)

        bst_ip_octets = []

        # range(0, 32, 8) means 0, 8, 16, 24

        for bit in range(0, 32, 8):
            bst_ip_octet = broadcast_address_binary[bit: bit + 8]
            bst_ip_octets.append(bst_ip_octet)

        # print(bst_ip_octets)

        bst_ip_address = []

        for each_octet in bst_ip_octets:
            bst_ip_address.append(str(int(each_octet, 2)))

        # print(bst_ip_address)

        broadcast_address = ".".join(bst_ip_address)
       

        # print(broadcast_address)

        # Results for selected IP/mask

        print("\n")
        print("Network address is: %s" % network_address)
        print("Broadcast address is: %s" % broadcast_address)
        print("Number of valid hosts per subnet: %s" % no_of_hosts)
        print("Wildcard mask: %s" % wildcard_mask)
        print("Mask bits: %s" % no_of_ones)
        print("\n")

        # Application #1 - Part #4

        # Generation of random IP addresses in the subnet

        while True:
            generate = input("Generate random IP address from this subnet? (y/n)")

            if generate == "y":
                generated_ip = []

                # Obtain available IP address in range, based on the difference between octets in broadcast address and network address

                for indexb, oct_bst in enumerate(bst_ip_address):

                    # print(indexb, oct_bst)

                    for indexn, oct_net in enumerate(net_ip_address):

                        # print(indexn, oct_net)

                        if indexb == indexn:
                            if oct_bst == oct_net:

                                # Add identical octets to the generated_ip list

                                generated_ip.append(oct_bst)
                            else:

                               # Generate random number(s) from within octet intervals and append to the list

                                generated_ip.append(str(random.randint(int(oct_net), int(oct_bst))))

                # IP address generated from the subnet pool

                # print(generated_ip)

                y_iaddr = ".".join(generated_ip)

                # print(y_iaddr)

                print("Random IP address is: %s" % y_iaddr)
                print("\n")
                continue

            else:
                print("Ok, bye!\n")
                break

    except KeyboardInterrupt:
        print("\n\nProgram aborted by user. Exiting...\n")
        sys.exit()

# Calling the function

subnet_calc()



Full code is as below.

import random
import sys

def subnet_calc():
    try:
        print("\n")

        while True:
            ip_address = input("Enter an IP address: ")

            ip_octets = ip_address.split('.')

            if (len(ip_octets) == 4) and (1 <= int(ip_octets[0]) <= 223) and (int(ip_octets[0]) != 127) and (
                    int(ip_octets[0]) != 169 or int(ip_octets[1]) != 254) and (
                    0 <= int(ip_octets[1]) <= 255 and 0 <= int(ip_octets[2]) <= 255 and 0 <= int(ip_octets[3]) <= 255):
                break

            else:
                print("\nThe IP address is INVALID! Please retry!\n")
                continue

        masks = [255, 254, 252, 248, 240, 224, 192, 128, 0]

        while True:
            subnet_mask = input("Enter a subnet mask: ")

            mask_octets = subnet_mask.split('.')

            if (len(mask_octets) == 4) and (int(mask_octets[0]) == 255) and (int(mask_octets[1]) in masks) and (
                    int(mask_octets[2]) in masks) and (int(mask_octets[3]) in masks) and (
                    int(mask_octets[0]) >= int(mask_octets[1]) >= int(mask_octets[2]) >= int(mask_octets[3])):
                break

            else:
                print("\nThe subnet mask is INVALID! Please retry!\n")
                continue
       
        mask_octets_binary = []

        for octet in mask_octets:
            binary_octet = bin(int(octet)).lstrip('0b')

            mask_octets_binary.append(binary_octet.zfill(8))


        binary_mask = "".join(mask_octets_binary)
 
		no_of_zeros = binary_mask.count("0")
        no_of_ones = 32 - no_of_zeros
        no_of_hosts = abs(2 ** no_of_zeros - 2)  

        wildcard_octets = []

        for octet in mask_octets:
            wild_octet = 255 - int(octet)
            wildcard_octets.append(str(wild_octet))


        wildcard_mask = ".".join(wildcard_octets)
        
        ip_octets_binary = []

        for octet in ip_octets:
            binary_octet = bin(int(octet)).lstrip('0b')

            ip_octets_binary.append(binary_octet.zfill(8))

        binary_ip = "".join(ip_octets_binary)

        network_address_binary = binary_ip[:(no_of_ones)] + "0" * no_of_zeros

        broadcast_address_binary = binary_ip[:(no_of_ones)] + "1" * no_of_zeros

        net_ip_octets = []

        for bit in range(0, 32, 8):
            net_ip_octet = network_address_binary[bit: bit + 8]
            net_ip_octets.append(net_ip_octet)

        net_ip_address = []

        for each_octet in net_ip_octets:
            net_ip_address.append(str(int(each_octet, 2)))

        network_address = ".".join(net_ip_address)

        bst_ip_octets = []

        for bit in range(0, 32, 8):
            bst_ip_octet = broadcast_address_binary[bit: bit + 8]
            bst_ip_octets.append(bst_ip_octet)

        bst_ip_address = []

        for each_octet in bst_ip_octets:
            bst_ip_address.append(str(int(each_octet, 2)))

        broadcast_address = ".".join(bst_ip_address)

        print("\n")
        print("Network address is: %s" % network_address)
        print("Broadcast address is: %s" % broadcast_address)
        print("Number of valid hosts per subnet: %s" % no_of_hosts)
        print("Wildcard mask: %s" % wildcard_mask)
        print("Mask bits: %s" % no_of_ones)
        print("\n")
       
        while True:
            generate = input("Generate random IP address from this subnet? (y/n)")

            if generate == "y":
                generated_ip = []

                
                for indexb, oct_bst in enumerate(bst_ip_address):
                    for indexn, oct_net in enumerate(net_ip_address):
                        if indexb == indexn:
                            if oct_bst == oct_net:
                                generated_ip.append(oct_bst)
                            else:
                                generated_ip.append(str(random.randint(int(oct_net), int(oct_bst))))

                y_iaddr = ".".join(generated_ip)

                print("Random IP address is: %s" % y_iaddr)
                print("\n")
                continue

            else:
                print("Ok, bye!\n")
                break

    except KeyboardInterrupt:
        print("\n\nProgram aborted by user. Exiting...\n")
        sys.exit()

subnet_calc()