logo hsb.horse
← Back to blog index

Blog

Implementing CIDR range IP address determination with TypeScript

For environments where external modules such as CloudFront Function cannot be used, we have implemented our own IP address determination within the CIDR range. Organized the implementation of class syntax using bitwise operations.

Published:

Implement your own IP address determination within the CIDR range in environments where it is difficult to use external modules such as CloudFront Function.

implementation

export class CIDR {
#cidr: string;
#baseIp: number;
#subnet: number;
constructor(cidr: string) {
this.#cidr = cidr;
const [baseIp, mask] = cidr.split("/");
this.#baseIp = this.#ipToLong(baseIp);
this.#subnet = this.#cidrToSubnet(Number.parseInt(mask, 10));
}
get cidr() {
return this.#cidr;
}
isInCidrRange(ip: string): boolean {
const ipLong = this.#ipToLong(ip);
const subnet = this.#subnet;
return (ipLong & subnet) === (this.#baseIp & subnet);
}
getCidrRange(): string[] {
const subnet = this.#subnet;
const startIp = this.#baseIp & subnet;
const endIp = startIp + (~subnet >>> 0);
const ips: string[] = [];
for (let i = startIp; i <= endIp; i++) {
ips.push(this.#longToIp(i));
}
return ips;
}
#ipToLong(ip: string): number {
return (
ip
.split(".")
.reduce((acc, octet) => (acc << 8) + Number.parseInt(octet, 10), 0) >>>
0
);
}
#longToIp(long: number): string {
const max = 255;
return [
(long >>> 24) & max,
(long >>> 16) & max,
(long >>> 8) & max,
long & max,
].join(".");
}
#cidrToSubnet(cidr: number): number {
return (-1 << (32 - cidr)) >>> 0;
}
}

How to use

const cidr = new CIDR("192.168.1.0/24");
// IPアドレスが範囲内かチェック
console.log(cidr.isInCidrRange("192.168.1.100")); // true
console.log(cidr.isInCidrRange("192.168.2.1")); // false
// CIDR範囲内の全IPアドレスを取得
const ips = cidr.getCidrRange();
console.log(ips.length); // 256

Points

Mutual conversion between IP address and long value

Bitwise operations are possible by converting an IP address (e.g. 192.168.1.1) to a 32-bit integer.

CIDR determination

Determine whether the IP address is within the CIDR range by performing an AND operation with the subnet mask.

(ipLong & subnet) === (baseIp & subnet)

Enumerate all IPs within range

Calculate the starting IP and ending IP and generate all IP addresses between them.

summary

Even in environments where external libraries cannot be used, you can implement CIDR determination yourself by using bitwise operations.

It can be used for IP control in CloudFront Function and other constrained environments.