Skip to content

Instantly share code, notes, and snippets.

@shiracamus
Created February 11, 2019 16:43
Show Gist options
  • Save shiracamus/becc6de3d91b448d271290abe52a174f to your computer and use it in GitHub Desktop.
Save shiracamus/becc6de3d91b448d271290abe52a174f to your computer and use it in GitHub Desktop.
from ipaddress import IPv4Address, IPv4Network, AddressValueError
def read_lines(filename):
try:
with open(filename) as f:
return f.read().splitlines()
except IOError:
print(f"Error: {filename}が開けない")
exit()
except UnicodeDecodeError:
print(f"Error: {filename}が読み込めない")
exit()
def write_lines(filename, lines):
try:
with open(filename, "w") as f:
print(*lines, sep="\n", file=f)
except IOError:
print("Error: {filename}が開けない")
exit()
def lines_to_addrs(lines):
try:
return [int(addr)
for line in lines
if line
for addr in IPv4Network(line)]
except AddressValueError as e:
print(f"Error : invalid IPv4 address ({e})")
exit()
def max_subnet_bits(addr):
for n in range(32):
if addr & (1 << n):
return n
return 32
def addrs_to_cidrs(addrs):
i, size = 0, len(addrs)
while i < size:
bits = max_subnet_bits(addrs[i])
for bit in range(bits, -1, -1):
n = 1 << bit
if i + n <= size and addrs[i + n - 1] == addrs[i] + n - 1:
yield IPv4Address(addrs[i]), 32 - bit
i += n
break
def cidrs_to_lines(cidrs, prefix32):
return [str(addr) + (f'/{prefix}' if prefix != 32 or prefix32 else '')
for addr, prefix in cidrs]
def main(in_file, out_file, prefix32=True):
lines = read_lines(in_file)
addrs = lines_to_addrs(lines)
addrs = sorted(set(addrs))
cidrs = addrs_to_cidrs(addrs)
lines = cidrs_to_lines(cidrs, prefix32)
write_lines(out_file, lines)
if __name__ == '__main__':
main(in_file="ip_list.txt", out_file="out_file.txt")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment