""" AUTHOR: Khushal P Soonderji DATE: Friday, 12th Jul., 2024 OBJECTIVE: To provide an easy way to get geolocation information of an IP address. REFERENCES: 1) https://medium.com/@tubelwj/how-to-retrieve-ip-geolocation-information-in-python-929e15041e3e DOWNLOADS: N/A """ # ***************************************************************************************************************** # ***** **** # *** IMPORT *** # ***** **** # ***************************************************************************************************************** # To make sibling directories accessible for imports: import sys sys.path.append(".") sys.path.append("..") # For working with IP Addresses: import ipaddress # ***************************************************************************************************************** # ***** **** # *** MACROS / ONE-TIME INIT *** # ***** **** # ***************************************************************************************************************** # --- Nothing Yet # ***************************************************************************************************************** # ***** **** # *** VARIABLES *** # ***** **** # ***************************************************************************************************************** # --- Nothing Yet # ***************************************************************************************************************** # ***** **** # *** FUNCTIONS *** # ***** **** # ***************************************************************************************************************** def ipv4_to_int(ip_string): """ Converts an IP (v4) string to an integer value. :param ip_string: The IP address (v4) that you want to convert to integer format. :return: An integer representation of the IP (v4) address. """ ip_numerical = int(ipaddress.IPv4Address(ip_string)) return ip_numerical # --------------------------------------------------------------------------------------------------------------------- def int_to_ipv4(ip_numerical): """ Interprets the IP (v4) value from the given integer value. :param ip_numerical: The integer value that represents an IP (v4) address. :return: """ ip_string = str(ipaddress.IPv4Address(ip_numerical)) return ip_string # --------------------------------------------------------------------------------------------------------------------- def ipv4_to_bin(ip_string): """ Converts an input IP (v4) address to the binary string that represents the 32 bits. :param ip_string: The IP (v4) string in a format like "192.168.0.1" :return: The binary representation (as a string) of the input IP address. """ ip_binary = bin(int(ipaddress.IPv4Address(ip_string)))[2:].zfill(32) return ip_binary # --------------------------------------------------------------------------------------------------------------------- def bin_to_ipv4(ip_binary): """ Interprets the IP (v4) value from the given binary string. :param ip_binary: The string of 1s and 0s that represents the IP (v4) address. :return: The IP (v4) address as a string. """ ip_string = str(ipaddress.IPv4Address(int(ip_binary, 2))) return ip_string # --------------------------------------------------------------------------------------------------------------------- def get_ipv4_range(ip_string, as_string = True): """ Given a network description in the format "88.95.100.128/25", this function tells you the first and last IP addresses of that network. Useful for determining if an IP address lies in a network. :param ip_string: The input network description in the format "88.95.100.128/25" :param as_string: To select between integer and string formats for the IP range output. :return: The first and last IP addresses of the input network, and the count. """ # Extract the components of the string: ip_components = ip_string.split("/") ip_addr = ipv4_to_int(ip_components[0]) ip_bits = int(ip_components[1]) # Convert the mask number to binary representation: ip_mask = (1 << ip_bits) - 1 ip_mask = ip_mask << (32 - ip_bits) inv_ip_mask = (~ip_mask) & 0xFFFF # Figure out the start and end IP addresses: start_ip = ip_addr & ip_mask end_ip = ip_addr | inv_ip_mask count = end_ip - start_ip + 1 # If the IPs are needed as strings, we perform the conversion: if as_string: start_ip = int_to_ipv4(start_ip) end_ip = int_to_ipv4(end_ip) # Done here: return start_ip, end_ip, count # ***************************************************************************************************************** # ***** **** # *** MAIN PROGRAM *** # ***** **** # ***************************************************************************************************************** if __name__ == "__main__": print(ipv4_to_int("255.255.255.255")) print(ipv4_to_int("x.x.x.x"))