IPアドレス判定
CloudFront Functionのような外部モジュールを使いづらいものを実装するときに、自前実装でなんとかできるように書いてみた。
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; }}