Разделение диапазонов
Разделение диапазонов — хитрая программа для разбиения одного диапазона на несколько.
Описание[править]
Как известно, каждый регистр IP-адреса содержит в себе как бы два подрегистра вдвое меньшего размера, например в подсети /16 имеется две подсети размером в /17, четыре подсети /18 и так далее. Но руками раскурлыкивать это напряжно.
Но в том возникла надобность из-за вандальных атак со стороны дятла, который стал назойливо долбить в стиле вонючей мухи. При этом он использовал очень разные диапазоны, но была проблема, а именно в части диапазонов могли сидеть нормальные русские аноны.
Встал вопрос о проверке, которую надо было проводить по диапазонам. Был оперативно найден программист, который стал внимательно изучать диапазон на предмет наличия определённых стран, которые не следует блокировать надолго. В итоге появилось целое семейство скриптов для разделения.
Работает это всё на Python, запуск можно спокойно сделать из Power Shell или даже крестьянского cmd.
Код[править]
split_16_to_19.py[править]
import sys
import ipaddress
def clean_cidr(raw_line):
"""
Fixes two common problems in your .txt file:
1. UTF-16 encoding → removes \x00 null bytes
2. Spaces between every character → "1 2 8 . 2 2 5 . 0 . 0 / 1 6" becomes "128.225.0.0/16"
"""
if not raw_line:
return ""
# Remove null bytes (UTF-16 artifact)
cleaned = raw_line.replace('\x00', '')
# Remove ALL whitespace and join the characters back together
cleaned = ''.join(cleaned.split())
return cleaned
def split_16_to_19(input_file, output_file=None):
"""
Reads your .txt file (even if it's UTF-16 or has weird spacing)
and expands every /16 into 8 /19 subnets.
"""
output_lines = []
# Try multiple encodings until one works (your file is likely UTF-16)
encodings = ['utf-8', 'utf-16', 'utf-16-le', 'windows-1252']
content = None
used_encoding = None
for enc in encodings:
try:
with open(input_file, 'r', encoding=enc, errors='replace') as f:
content = f.readlines()
used_encoding = enc
print(f"✅ Successfully opened file using {enc} encoding.")
break
except Exception:
continue
if content is None:
# Fallback: read as raw bytes and clean
with open(input_file, 'rb') as f:
raw = f.read()
content = raw.decode('utf-8', errors='replace').splitlines()
print("✅ Opened file with fallback raw decoding.")
for line_num, line in enumerate(content, 1):
cidr = clean_cidr(line)
if not cidr or cidr.startswith('#'):
continue # skip empty lines and comments
try:
net = ipaddress.ip_network(cidr, strict=False)
if net.version != 4:
print(f"Warning: Line {line_num} is not IPv4 - skipping", file=sys.stderr)
continue
if net.prefixlen != 16:
print(f"Warning: Line {line_num} '{cidr}' is not a /16 (found /{net.prefixlen})", file=sys.stderr)
# Split into exactly 8 /19 subnets
for subnet in net.subnets(new_prefix=19):
output_lines.append(str(subnet) + '\n')
except ValueError as e:
print(f"Error on line {line_num} after cleaning '{cidr}': {e}", file=sys.stderr)
if not output_lines:
print("❌ No valid /16 ranges found after cleaning. Check your file.")
return
if output_file:
with open(output_file, 'w', encoding='utf-8') as f:
f.writelines(output_lines)
print(f"✅ Done! Wrote {len(output_lines)} /19 ranges to '{output_file}'")
else:
sys.stdout.writelines(output_lines)
print(f"✅ Done! Printed {len(output_lines)} /19 ranges to console")
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Usage:")
print(" python split_16_to_19_fixed.py your_ranges.txt")
print(" python split_16_to_19_fixed.py your_ranges.txt output_19s.txt")
print("\n(The script now automatically fixes UTF-16 null bytes and spaces between digits.)")
sys.exit(1)
input_file = sys.argv[1]
output_file = sys.argv[2] if len(sys.argv) > 2 else None
split_16_to_19(input_file, output_file)
split_19_to_21.py[править]
import sys
import ipaddress
def clean_cidr(raw_line):
"""
Fixes two common problems in .txt files:
1. UTF-16 encoding → removes \x00 null bytes
2. Spaces between every character → "1 2 8 . 2 2 5 . 0 . 0 / 1 9" becomes "128.225.0.0/19"
"""
if not raw_line:
return ""
# Remove null bytes (UTF-16 artifact)
cleaned = raw_line.replace('\x00', '')
# Remove ALL whitespace and join the characters back together
cleaned = ''.join(cleaned.split())
return cleaned
def split_19_to_21(input_file, output_file=None):
"""
Reads a .txt file containing one IPv4 /19 CIDR per line
(even if it's UTF-16 or has weird spacing)
and expands each into its 4 corresponding /21 subnets.
"""
output_lines = []
# Try multiple encodings until one works (your previous file was likely UTF-16)
encodings = ['utf-8', 'utf-16', 'utf-16-le', 'windows-1252']
content = None
used_encoding = None
for enc in encodings:
try:
with open(input_file, 'r', encoding=enc, errors='replace') as f:
content = f.readlines()
used_encoding = enc
print(f"✅ Successfully opened file using {enc} encoding.")
break
except Exception:
continue
if content is None:
# Fallback: read as raw bytes and clean
with open(input_file, 'rb') as f:
raw = f.read()
content = raw.decode('utf-8', errors='replace').splitlines()
print("✅ Opened file with fallback raw decoding.")
for line_num, line in enumerate(content, 1):
cidr = clean_cidr(line)
if not cidr or cidr.startswith('#'):
continue # skip empty lines and comments
try:
net = ipaddress.ip_network(cidr, strict=False)
if net.version != 4:
print(f"Warning: Line {line_num} is not IPv4 - skipping", file=sys.stderr)
continue
if net.prefixlen != 19:
print(f"Warning: Line {line_num} '{cidr}' is not a /19 (found /{net.prefixlen})", file=sys.stderr)
# Split into exactly 4 /21 subnets
for subnet in net.subnets(new_prefix=21):
output_lines.append(str(subnet) + '\n')
except ValueError as e:
print(f"Error on line {line_num} after cleaning '{cidr}': {e}", file=sys.stderr)
if not output_lines:
print("❌ No valid /19 ranges found after cleaning. Check your file.")
return
if output_file:
with open(output_file, 'w', encoding='utf-8') as f:
f.writelines(output_lines)
print(f"✅ Done! Wrote {len(output_lines)} /21 ranges to '{output_file}'")
else:
sys.stdout.writelines(output_lines)
print(f"✅ Done! Printed {len(output_lines)} /21 ranges to console")
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Usage:")
print(" python split_19_to_21.py your_19_ranges.txt")
print(" python split_19_to_21.py your_19_ranges.txt output_21s.txt")
print("\n(The script automatically fixes UTF-16 null bytes and spaces between digits if needed.)")
sys.exit(1)
input_file = sys.argv[1]
output_file = sys.argv[2] if len(sys.argv) > 2 else None
split_19_to_21(input_file, output_file)
split_21_to_24.py[править]
import sys
import ipaddress
def clean_cidr(raw_line):
"""
Fixes two common problems in .txt files:
1. UTF-16 encoding → removes \x00 null bytes
2. Spaces between every character → "1 2 8 . 2 2 5 . 0 . 0 / 2 1" becomes "128.225.0.0/21"
"""
if not raw_line:
return ""
# Remove null bytes (UTF-16 artifact)
cleaned = raw_line.replace('\x00', '')
# Remove ALL whitespace and join the characters back together
cleaned = ''.join(cleaned.split())
return cleaned
def split_21_to_24(input_file, output_file=None):
"""
Reads a .txt file containing one IPv4 /21 CIDR per line
(even if it's UTF-16 or has weird spacing)
and expands each into its 8 corresponding /24 subnets.
"""
output_lines = []
# Try multiple encodings until one works (your previous files were likely UTF-16)
encodings = ['utf-8', 'utf-16', 'utf-16-le', 'windows-1252']
content = None
used_encoding = None
for enc in encodings:
try:
with open(input_file, 'r', encoding=enc, errors='replace') as f:
content = f.readlines()
used_encoding = enc
print(f"✅ Successfully opened file using {enc} encoding.")
break
except Exception:
continue
if content is None:
# Fallback: read as raw bytes and clean
with open(input_file, 'rb') as f:
raw = f.read()
content = raw.decode('utf-8', errors='replace').splitlines()
print("✅ Opened file with fallback raw decoding.")
for line_num, line in enumerate(content, 1):
cidr = clean_cidr(line)
if not cidr or cidr.startswith('#'):
continue # skip empty lines and comments
try:
net = ipaddress.ip_network(cidr, strict=False)
if net.version != 4:
print(f"Warning: Line {line_num} is not IPv4 - skipping", file=sys.stderr)
continue
if net.prefixlen != 21:
print(f"Warning: Line {line_num} '{cidr}' is not a /21 (found /{net.prefixlen})", file=sys.stderr)
# Split into exactly 8 /24 subnets
for subnet in net.subnets(new_prefix=24):
output_lines.append(str(subnet) + '\n')
except ValueError as e:
print(f"Error on line {line_num} after cleaning '{cidr}': {e}", file=sys.stderr)
if not output_lines:
print("❌ No valid /21 ranges found after cleaning. Check your file.")
return
if output_file:
with open(output_file, 'w', encoding='utf-8') as f:
f.writelines(output_lines)
print(f"✅ Done! Wrote {len(output_lines)} /24 ranges to '{output_file}'")
else:
sys.stdout.writelines(output_lines)
print(f"✅ Done! Printed {len(output_lines)} /24 ranges to console")
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Usage:")
print(" python split_21_to_24.py your_21_ranges.txt")
print(" python split_21_to_24.py your_21_ranges.txt output_24s.txt")
print("\n(The script automatically fixes UTF-16 null bytes and spaces between digits if needed.)")
sys.exit(1)
input_file = sys.argv[1]
output_file = sys.argv[2] if len(sys.argv) > 2 else None
split_21_to_24(input_file, output_file)