#!/usr/bin/env python3 # Convert a TSV file to a asn.txt # Source: # range_start range_end AS_number country_code AS_description # Result: # subnet/mask AS_number AS_description country_code # 1.0.0.0/24 13335 eetc US # 1.0.4.0/22 38803 etc AU import sys import ipaddress import csv def calculate_subnets(line_list): subnets = [] while True: # Calculate from diff of range_start and range_end subnet size # 1.1.1.0 1.1.2.0 = 256 subnet1_uint32 = int(ipaddress.IPv4Address(line_list[0])) subnet2_uint32 = int(ipaddress.IPv4Address(line_list[1])) subnet_size = subnet2_uint32 - subnet1_uint32 # calculate bitmask subnet_mask = 32 - subnet_size.bit_length() # is subnet not exact size of 2^n? verify using subnet_mask p2 = (2**(32-subnet_mask))-1 if subnet_size != p2: #print(f'Error: {line} is not a power of 2 {subnet_size} {subnet_mask} {p2}') # Calculate next subnet subnet_mask = subnet_mask + 1 subnets.append(f'{line_list[0]}/{subnet_mask}') #print(f'Adding {line_list[0]}/{subnet_mask}') # Calculate next subnet subnet1_uint32 = subnet1_uint32 + (2**(32-subnet_mask)) printable_subnet = str(ipaddress.IPv4Address(subnet1_uint32)) #print(f'Next subnet {printable_subnet}') # if next subnet is not in range, break if subnet1_uint32 > subnet2_uint32: print(f'Error: Subnet {subnet1_uint32} is not in range {subnet2_uint32}') break line_list[0] = str(ipaddress.IPv4Address(subnet1_uint32)) else: # Add subnet to subnets subnets.append(f'{line_list[0]}/{subnet_mask}') break return subnets def main(): # argv[1] is the input file # argv[2] is the output file if len(sys.argv) != 3: print("Usage: convert_tsv.py ") sys.exit(1) # Open the input file try: input_file = open(sys.argv[1], 'r') except IOError: print("Error: Cannot open input file") sys.exit(1) # Open the output file try: output_file = csv.writer(open(sys.argv[2], 'w'), delimiter=',',doublequote=True,quoting=csv.QUOTE_ALL) except IOError: print("Error: Cannot open output file") sys.exit(1) # Read the input file line by line for line in input_file: # strip the newline at the end of the line line = line.rstrip('\n') # Split the line into a list by tabs line_list = line.split('\t') subnets = calculate_subnets(line_list) for subnet in subnets: #print(line_list[2] + '\t' + line_list[4] + '\t' + line_list[3] + '\t' + subnet) # CSV output_file.writerow([subnet, line_list[2], line_list[4], line_list[3]]) # Write the output file #output_file.write(str(subnet) + '\t' + line_list[2] + '\t' + line_list[4] + '\t' + line_list[3] + '\n') input_file.close() if __name__ == '__main__': main()