Skip to content

Instantly share code, notes, and snippets.

@nil0x42
Last active June 2, 2021 17:18
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nil0x42/943c2691e2130252091224e3dda059db to your computer and use it in GitHub Desktop.
Save nil0x42/943c2691e2130252091224e3dda059db to your computer and use it in GitHub Desktop.
Quickly check if an IPv4 is contained in a list of subnets.
import struct
import socket
class SubnetList:
"""Quickly check if an IPv4 is contained in a list of subnets.
- by @nil0x42
- inspired by @nigel222's solution: https://stackoverflow.com/a/44264136
>>> cloudflare_ips = SubnetList("/wordlists/cloudflare-ips.txt")
>>> "103.31.4.12" in cloudflare_ips
True
>>> "127.0.0.1" in cloudflare_ips
False
"""
def __init__(self, subnets_path=None):
self.subnets = [set() for x in range(32+1)]
if subnets_path:
for line in open(subnets_path):
line = line.strip()
if not line or line.startswith("#"):
continue
self.add(line)
def __contains__(self, ip):
ip = self._ip2int(ip)
for N in range(32, 7, -1): # check N from 32 to 8
mask = 0xffffffff >> 32-N << 32-N
if ip & mask in self.subnets[N]:
return True
return False
def add(self, subnet):
if "/" in subnet:
network, N = subnet.split('/')
N = int(N)
assert 8 <= N <= 32, "invalid subnet mask in %r" % subnet
else:
network, N = subnet, 32
network = self._ip2int(network)
self.subnets[N].add(network >> 32-N << 32-N)
def _ip2int(self, ip):
return struct.unpack("!I", socket.inet_aton(ip))[0]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment