summaryrefslogtreecommitdiff
path: root/legacy/OG_v1.py
blob: 7f06c2c1f8280dab10e91ae54f36946b851ea7f0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import re
import math
import json
from typing import no_type_check

valid_ranges = [
    {
        "ip": "00001010000000000000000000000000", # 10.0.0.0/8
        "sub":"11111111000000000000000000000000"
    },
    {
        "ip": "10101100000100000000000000000000", # 172.16.0.0/12
        "sub":"11111111111100000000000000000000"
    },
    {
        "ip": "11000000101010000000000000000000", # 192.168.0.0/16
        "sub":"11111111111111110000000000000000"
    }
]
SUBNETLENGTH = 32

ip_regex = re.compile("^([0-9]{1,3}\\.){3}[0-9]{1,3}/[0-9]{1,2}$")

def compIpSub(ip1, ip2, sub):
    for i,ii,s in zip(ip1, ip2, sub):
        if s == '1':
            if i != ii:
                return False
    return True

def convSubBin(sub):
    a = "1"*int(sub)
    return f'{a:0<32}'

def convDecBin(dec):
    return "{:08b}".format(int(dec))

def convIpBin(ip):
    out_string = ""
    for seg in ip.split("."):
        out_string += convDecBin(seg)
    return out_string

def convBinIp(ip):
    segemnts = []
    # https://stackoverflow.com/questions/9475241/split-string-every-nth-character
    for seg in [ip[i:i+8] for i in range(0,len(ip), 8)][:4]: 
        segemnts.append(str(int(seg, 2)))
    return ".".join(segemnts)

while True:
    input_str = input("Entrez l'addresse réseau ").strip() # Strip remove newline char
    if not ip_regex.match(input_str):
        print("IP Invalide")
        continue
    
    ip_cleaned = input_str.split("/")[0]
    subnet_cleaned = input_str.split("/")[1]

    # Since we're converting into binary, we don't want anything bigger than 8bit integers
    for ip_seg in ip_cleaned.split("."):
        if int(ip_seg,10) > 255:
            print("IP Invalide")
            continue

    # Convert the ip and subnet into bin
    net_bin = convIpBin(ip_cleaned)
    sub_bin = convSubBin(subnet_cleaned)

    # Check if the ip is in one of the apropriate ranges
    for i in valid_ranges:
        if compIpSub(i["ip"], net_bin, i["sub"]):
            break
    else:
        print("L'IP n'est pas dans un range valid pour un réseau privé")
        continue
    # Get the desired subnet size
    input_str = input("Entrez le nombre d'addresses désirés: ").strip() # Strip to remove unwanted newline

    try:
        min_net_size = int(input_str) + 2
    except:
        print("Nombre invalide")
        continue
    
    # Convert subnet into binary
    target_sub_bin = convSubBin(SUBNETLENGTH - len(str(bin(min_net_size))[2:]))
    sub_size_diff = target_sub_bin.count("1") - sub_bin.count("1") # ex: /28 - /24 == 4, but in binary so num of 1s
    if sub_size_diff <= 0:
        print("Sous réseau requis plus grand ou égal à celui du réseau")
        continue


    # Get all networks in between the subnets
    # WARNING, entering legacy  i dont understand anymore code territory
    net_start = net_bin[:sub_bin.count("1")]
    net_size = int(math.pow(2, target_sub_bin.count("0")))

    networks = []
    current_net_offset = 0
    while current_net_offset < math.pow(2, sub_size_diff)*net_size: #umm, math stuff, size diff how much room we have in binary for new nets, we gotta convert that room to int (pow) and offset by its position in the bin string (*)
        new_net_bin = net_start + str(bin(current_net_offset))[2:].zfill(sub_bin.count("0")) # we strip 2 first chars as it is the type identifier, we also zfill because they are right padded and we need the correct size, if we left pad we will get a no good data
        networks.append(convBinIp(new_net_bin))
        current_net_offset += net_size

    print("\n".join(networks))