forked from echo-corp/argo-ip-radar
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathip_gen.py
More file actions
93 lines (73 loc) · 2.78 KB
/
Copy pathip_gen.py
File metadata and controls
93 lines (73 loc) · 2.78 KB
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
import argparse
import ipaddress
import json
import os
import random
CONFIG_FILE = "subnets.json"
DEFAULT_COUNT = 1000
DEFAULT_OUTPUT_FILE = "ips.txt"
def positive_int(value):
parsed = int(value)
if parsed <= 0:
raise argparse.ArgumentTypeError("must be greater than 0")
return parsed
def get_subnet_weight(value):
if isinstance(value, dict):
return max(0.01, float(value.get("weight", 0.1)))
return max(0.01, float(value))
def generate_weighted_ips(count=DEFAULT_COUNT, output_file=DEFAULT_OUTPUT_FILE, config_file=CONFIG_FILE):
"""
Generates `count` Cloudflare IPs weighted by performance recorded in `config_file`.
Writes them to `output_file` (if output_file is not None) and returns the list of IPs.
"""
if not os.path.exists(config_file):
raise FileNotFoundError(f"Subnets file '{config_file}' not found.")
with open(config_file, "r") as f:
subnet_data = json.load(f)
subnets = list(subnet_data.keys())
if not subnets:
raise ValueError("No subnets found in configuration file.")
weights = [get_subnet_weight(value) for value in subnet_data.values()]
# Select subnets based on weights
chosen_subnets = random.choices(subnets, weights=weights, k=count)
generated_ips = []
for cidr in chosen_subnets:
net = ipaddress.ip_network(cidr)
# Avoid network and broadcast address if possible
if net.num_addresses > 2:
idx = random.randint(1, net.num_addresses - 2)
else:
idx = random.randint(0, net.num_addresses - 1)
random_ip = str(net[idx])
generated_ips.append(random_ip)
if output_file:
os.makedirs(os.path.dirname(output_file) if os.path.dirname(output_file) else ".", exist_ok=True)
with open(output_file, "w") as f:
for ip in generated_ips:
f.write(ip + "\n")
print(f"Generated {len(generated_ips)} IPs weighted by subnet performance into {output_file}.")
return generated_ips
def parse_args():
parser = argparse.ArgumentParser(description="Generate weighted Cloudflare IP candidates.")
parser.add_argument(
"-n", "--count",
type=positive_int,
default=DEFAULT_COUNT,
help=f"Number of IPs to generate (default: {DEFAULT_COUNT})."
)
parser.add_argument(
"-o", "--output",
default=DEFAULT_OUTPUT_FILE,
help=f"Destination file for generated IPs (default: {DEFAULT_OUTPUT_FILE})."
)
parser.add_argument(
"-s", "--config",
default=CONFIG_FILE,
help=f"Path to subnets JSON file (default: {CONFIG_FILE})."
)
return parser.parse_args()
def main():
args = parse_args()
generate_weighted_ips(args.count, args.output, args.config)
if __name__ == "__main__":
main()