IPv4 CIDR Range Matcher
Convert IPv4 addresses to integers and test membership in CIDR blocks for allowlists, proxies and rate limits.
Code
export interface ParsedCidr {
network: number;
mask: number;
prefix: number;
}
export function ipv4ToInt(address: string): number {
const parts = address.split(".");
if (parts.length !== 4) throw new TypeError("invalid IPv4 address: " + address);
let value = 0;
for (const part of parts) {
if (!/^\d{1,3}$/.test(part)) throw new TypeError("invalid IPv4 octet: " + part);
if (part.length > 1 && part.startsWith("0")) throw new RangeError("leading zeros are not allowed");
const octet = Number(part);
if (octet > 255) throw new RangeError("IPv4 octet out of range: " + part);
value = value * 256 + octet;
}
return value >>> 0;
}
export function parseCidr(cidr: string): ParsedCidr {
const parts = cidr.split("/");
if (parts.length !== 2) throw new SyntaxError("CIDR must contain one slash");
const address = parts[0]!;
const prefix = Number(parts[1]!);
if (!Number.isInteger(prefix) || prefix < 0 || prefix > 32) {
throw new RangeError("CIDR prefix must be an integer between 0 and 32");
}
const mask = prefix === 0 ? 0 : (0xffffffff << (32 - prefix)) >>> 0;
return { network: (ipv4ToInt(address) & mask) >>> 0, mask, prefix };
}
export function isIpInCidr(address: string, cidr: string): boolean {
const { network, mask } = parseCidr(cidr);
return ((ipv4ToInt(address) & mask) >>> 0) === network;
}Report a problem with this exampleOpens a pre-filled issue on GitHub.