How to Generate Random IP Addresses for Network Testing: IPv4, IPv6, CIDR, and Bogon Filtering
By Khizar Tahir · Founder & Developer, Casetivo
IP addresses represent the fundamental routing coordinates of the global internet. Every incoming HTTP request, DNS query, firewall packet filter, intrusion detection alert, and analytics log references an Internet Protocol address.
When building network monitoring tools, Web Application Firewalls (WAF), load balancer rate limiters, or geo-location lookups, software engineers cannot rely on testing with a single localhost address (127.0.0.1) or a handful of hardcoded internal IPs. To properly benchmark network filters, verify subnet masks, and stress-test log aggregation pipelines, teams need the ability to procedurally generate hundreds or thousands of realistic IPv4 and IPv6 addresses on demand.
In this deep dive, we will examine the bitwise anatomy of IPv4 and IPv6 addresses, investigate RFC 1918 private networks versus public routable spaces, understand bogon IP filtering, and demonstrate how our client-side Random IP Address Generator allows engineers to synthesize high-volume, compliant test data directly in the browser.
1. Bitwise Architecture: IPv4 vs. IPv6
Before writing generators, developers must grasp the binary structures governing the two primary internet protocol versions:
+--------------------------------------------------------------------------+
| Internet Protocol Architecture Matrix |
+--------------------------------------------------------------------------+
| Feature | IPv4 | IPv6 |
+----------------------+---------------------------+-----------------------+
| Bit Length | 32 bits (4 octets) | 128 bits (16 octets) |
| Address Space | 2^32 (~4.29 billion) | 2^128 (~3.4 x 10^38) |
| Notation | Dotted-decimal (0-255) | 8 groups of 4 hex digits
| Example | 198.51.100.24 | 2001:0db8:85a3::8a2e |
| Subnet Notation | CIDR (e.g., /24) | CIDR (e.g., /64) |
| Loopback | 127.0.0.1 | ::1 |
| Private Range Spec | RFC 1918 | RFC 4193 (ULA) |
+--------------------------------------------------------------------------+
The 32-Bit Anatomy of IPv4
An IPv4 address consists of 32 binary bits divided into four 8-bit octets:
$$\text{IP} = \text{Octet}_1 . \text{Octet}_2 . \text{Octet}_3 . \text{Octet}_4$$
Each octet represents an integer from $0$ to $255$ ($2^8 - 1$). In binary, the address 192.0.2.1 corresponds to:
$$11000000 . 00000000 . 00000010 . 00000001$$
Because the entire address fits cleanly inside a single 32-bit unsigned integer, an IPv4 address can be manipulated using bitwise shift operators (>>, <<) and bitwise masks (&, |).
The 128-Bit Vastness of IPv6
IPv6 was created to solve IPv4 address exhaustion, expanding the address pool to 128 bits. Represented as eight groups of four hexadecimal digits separated by colons, IPv6 supports shorthand zero compression using double colons (::). For example, 2001:0db8:0000:0000:0000:0000:0000:0001 simplifies to 2001:db8::1.
2. Special IP Ranges, RFC 1918, and Bogon Filtering
When generating random IP addresses for testing, blindly picking random integers across the $0$ to $2^{32}-1$ space generates addresses that are invalid or reserved. Depending on your testing scenario, you must categorize addresses into distinct network classes:
A. Private Networks (RFC 1918)
Private IP ranges are reserved for internal local area networks (LANs) and are never routed across the public internet:
10.0.0.0/8: Single Class A network spanning10.0.0.0to10.255.255.255($16,777,216$ addresses). Widely used in cloud VPCs like AWS, GCP, and Azure.172.16.0.0/12: 16 contiguous Class B networks spanning172.16.0.0to172.31.255.255($1,048,576$ addresses). Common in Docker container networks.192.168.0.0/16: 256 Class C networks spanning192.168.0.0to192.168.255.255($65,536$ addresses). Default in home routers and small office Wi-Fi setups.
B. Documentation and Example Ranges (RFC 5737)
When writing technical documentation, software manuals, or test fixtures that might be shared publicly, using live public IP addresses can inadvertently point traffic at innocent third parties. The IETF designated three blocks specifically for documentation:
192.0.2.0/24(TEST-NET-1)198.51.100.0/24(TEST-NET-2)203.0.113.0/24(TEST-NET-3)
C. Bogon IP Filtering
A bogon is an IP address that should not appear on the public internet routing table. This includes unallocated address space, loopback (127.0.0.0/8), link-local (169.254.0.0/16), and multicast blocks (224.0.0.0/4). Firewalls, intrusion prevention systems (IPS), and DDoS mitigation appliances maintain bogon filter lists to drop spoofed packets immediately at the network edge.
+--------------------------------------------------------------------------+
| IPv4 Address Space Distribution |
+--------------------------------------------------------------------------+
| |
| [0.0.0.0/8] ---> Current Network (Invalid as source/dest) |
| [10.0.0.0/8] ---> RFC 1918 Private Cloud / Corporate LAN |
| [127.0.0.0/8] ---> Host Loopback Interface |
| [169.254.0.0/16] ---> APIPA / Link-Local Auto-Configuration |
| [172.16.0.0/12] ---> RFC 1918 Private Docker / Subnets |
| [192.168.0.0/16] ---> RFC 1918 Home Routers / Office LANs |
| [224.0.0.0/4] ---> Multicast Routing Protocol Space |
| [240.0.0.0/4] ---> Reserved for "Future Use" (Historically unused) |
| |
| [All Other Blocks]---> Routable Public Internet (Web, APIs, CDNs) |
| |
+--------------------------------------------------------------------------+
3. Algorithmic IP Generation in TypeScript
Generating random IP addresses requires high-entropy random byte extraction paired with network boundary enforcement.
Here is an architectural implementation illustrating how to generate public IPv4, private RFC 1918 IPv4, and random IPv6 addresses:
/**
* Generates a random public, routable IPv4 address.
* Excludes private networks, loopback, multicast, and reserved blocks.
*/
export function generateRandomPublicIPv4(): string {
const buffer = new Uint8Array(4);
while (true) {
window.crypto.getRandomValues(buffer);
const first = buffer[0];
const second = buffer[1];
// Filter out 0.x (Current network), 10.x (RFC 1918 Private), 127.x (Loopback)
if (first === 0 || first === 10 || first === 127) continue;
// Filter out 169.254.x (Link-local)
if (first === 169 && second === 254) continue;
// Filter out 172.16.x - 172.31.x (RFC 1918 Private)
if (first === 172 && second >= 16 && second <= 31) continue;
// Filter out 192.168.x (RFC 1918 Private)
if (first === 192 && second === 168) continue;
// Filter out 224.0.0.0+ (Multicast and Reserved Class E)
if (first >= 224) continue;
return `${buffer[0]}.${buffer[1]}.${buffer[2]}.${buffer[3]}`;
}
}
/**
* Generates a random RFC 1918 private IPv4 address.
*/
export function generateRandomPrivateIPv4(subnet?: "10" | "172" | "192"): string {
const buffer = new Uint8Array(4);
window.crypto.getRandomValues(buffer);
const choice = subnet || (["10", "172", "192"][buffer[0] % 3] as "10" | "172" | "192");
if (choice === "10") {
// 10.0.0.0 to 10.255.255.255
return `10.${buffer[1]}.${buffer[2]}.${buffer[3]}`;
} else if (choice === "172") {
// 172.16.0.0 to 172.31.255.255
const secondOctet = 16 + (buffer[1] % 16);
return `172.${secondOctet}.${buffer[2]}.${buffer[3]}`;
} else {
// 192.168.0.0 to 192.168.255.255
return `192.168.${buffer[2]}.${buffer[3]}`;
}
}
/**
* Generates a random globally scoped IPv6 address (2000::/3).
*/
export function generateRandomIPv6(): string {
const buffer = new Uint16Array(8);
window.crypto.getRandomValues(buffer);
// Enforce global unicast prefix (2000::/3 -> first block 0x2000 to 0x3FFF)
buffer[0] = 0x2000 + (buffer[0] % 0x2000);
const hexGroups = Array.from(buffer).map((val) => val.toString(16).padStart(4, "0"));
return hexGroups.join(":");
}
4. Testing Use Cases: Firewalls, Loggers, and WAFs
Why do engineering teams generate hundreds of synthetic IP addresses?
1. WAF and Rate Limiter Stress Testing
Modern API gateways (like Envoy, NGINX, or Cloudflare Workers) throttle requests based on client IP addresses. When testing rate limiting in staging environments, requests from automated test runners all arrive from a single runner IP. By spoofing the X-Forwarded-For header with procedurally generated IPs, load testing suites can simulate millions of distinct, simultaneous clients from across the globe.
2. Geo-IP and CDN Routing Verification
Applications that serve geo-targeted content or localized currencies utilize databases like MaxMind GeoIP2. By piping generated IP batches through lookup services, developers verify that regional routing fallbacks, locale selectors, and tax calculation engines function accurately without manual proxy configuration.
3. SIEM and Log Pipeline Benchmarking
Security Information and Event Management (SIEM) platforms like Splunk, Datadog, or Elasticsearch ingest gigabytes of access logs daily. Seeding synthetic logs with varied IP addresses, paired with user agents and mock timestamps from the Random Data Generator, ensures log indexing clusters and query caches are benchmarked under genuine high-cardinality conditions.
5. Security & Privacy Considerations
Using synthetic IP addresses protects operational privacy and prevents unintended collateral impacts:
- Zero Accidental Denial-of-Service: Sending millions of stress-test packets to hardcoded external IP addresses can inadvertently overwhelm third-party servers. Using documentation ranges or synthetic private pools prevents accidental scanning incidents.
- Client-Side Generation Safety: Using Casetivo's Random IP Address Generator ensures all values are synthesized directly in your browser's local sandbox using the Web Crypto API. No IP strings are transmitted across the network, preserving strict test isolation.
By leveraging procedural IP generation with proper subnet awareness, engineers can build resilient network defenses, robust analytics pipelines, and secure cloud architectures.