An Internet Protocol address (IP address) uniquely identifies each computer or device on a network, such as the Internet.
There are two types of IP addresses, IPv4 and IPv6. I haven’t used IPv6 in my time with the library.
IPv4 addresses:
This is the most widely used IP address format today.
- It uses 32 bits and represents them as four numbers separated by dots (e.g., 192.168.1.1).
- It provides about 4.3 billion unique addresses.
IPv6 addresses:
This is a new format introduced to address the exhaustion of IPv4 addresses, and it’s not used very much.
- It uses 128 bits and represents them as a hexadecimal number divided into eight groups, separated by colons (e.g., 2001:0db8:85a3:0000:0000:8a2e:0370:7334).
- This provides a nearly infinite address space.
This IP addressing in Python is handled by the ipaddress
(Python Document) library. This library is one of the standard library additions since Python 3.3, with modules to help you create, manipulate, and inspect IP addresses, networks, and subnet masks.
Key Features
- Create and Manipulate IP Addresses
Generate IP address objects from strings or integers to perform various operations on IP addresses. - Networks and Subnets
Easily create and manage IP network addresses, calculate host IPs within a network, or represent subnets (IP ranges). - Address Validation
Check whether a given IP address belongs to a specific network, if it is a public or private IP address, and more. - Interface Addresses
Manage IP addresses assigned to network interfaces, along with the network addresses they belong to.
IP address Code
from ipaddress import IPv4Network
from ipaddress import IPv4Address
IPv4Address(3691907365) # IPv4Address('220.14.9.37')
addr = IPv4Address(b"\xdc\x0e\t%") # IPv4Address('220.14.9.37')
print(int(addr)) # 3691907365
print(addr.packed) # b'\xdc\x0e\t%'
net = IPv4Network("192.4.2.0/24")
print(net.num_addresses) # 256
print(net.prefixlen) # 24
print(net.netmask) # IPv4Address('255.255.255.0')
print(IPv4Address("192.4.2.12") in net) # True
print(IPv4Address("192.4.20.2") in net) # False
print(IPv4Network("192.4.2.0/255.255.255.0")) # IPv4Network('192.4.2.0/24')
print(net.broadcast_address) # IPv4Address('192.4.2.255')
for addr in net:
print(addr)
'''
192.4.2.0
192.4.2.1
192.4.2.2
. . .
192.4.2.13
192.4.2.14
192.4.2.15
'''
h = net.hosts()
print(type(h)) # <class 'generator'>
print(next(h)) # IPv4Address('192.4.2.1')
print(next(h)) # IPv4Address('192.4.2.2')
small_net = IPv4Network("192.0.2.0/28")
big_net = IPv4Network("192.0.0.0/16")
print(small_net.subnet_of(big_net)) # True
print(big_net.supernet_of(small_net)) # True
if IPv4Address('192.0.0.1') in IPv4Network("192.0.0.0/16"): #True
print("Subnet")
Output
3691907365
b'xdcx0et%'
256
24
255.255.255.0
True
False
192.4.2.0/24
192.4.2.255
192.4.2.0
192.4.2.1
....
192.4.2.254
192.4.2.255
<class 'generator'>
192.4.2.1
192.4.2.2
True
True
Subnet
You can manipulate or validate network IP addresses in many ways using these features. I still remember when I first started working with data, I had no idea such functions existed, which led to a lot of challenges.
For instance, I once had to write a simple Python script to search for IPs within a specific range. The task involved checking if 130,000 IPs were included in 5,000 subnets—an effort that would have been much easier with the right tools.