diff options
| author | ST-DDT <[email protected]> | 2024-10-10 18:14:30 +0200 |
|---|---|---|
| committer | GitHub <[email protected]> | 2024-10-10 18:14:30 +0200 |
| commit | a5a6c5b4e1145b1e21e5d8e540bc6f55f97d3a84 (patch) | |
| tree | 085617f44738e2e262bb958ffa00ae17e703c1cf /src/modules | |
| parent | 5b1c8588f8a57be712e64434f7b17a8407a4f465 (diff) | |
| download | faker-a5a6c5b4e1145b1e21e5d8e540bc6f55f97d3a84.tar.xz faker-a5a6c5b4e1145b1e21e5d8e540bc6f55f97d3a84.zip | |
feat(internet): improve ipv4 method (#2992)
Diffstat (limited to 'src/modules')
| -rw-r--r-- | src/modules/internet/index.ts | 170 |
1 files changed, 166 insertions, 4 deletions
diff --git a/src/modules/internet/index.ts b/src/modules/internet/index.ts index f6884d88..a455135b 100644 --- a/src/modules/internet/index.ts +++ b/src/modules/internet/index.ts @@ -1,3 +1,4 @@ +import { FakerError } from '../../errors/faker-error'; import { ModuleBase } from '../../internal/module-base'; import { charMapping } from './char-mappings'; import * as random_ua from './user-agent'; @@ -23,6 +24,82 @@ export type HTTPStatusCodeType = export type HTTPProtocolType = 'http' | 'https'; +export enum IPv4Network { + /** + * Equivalent to: `0.0.0.0/0` + */ + Any = 'any', + /** + * Equivalent to: `127.0.0.0/8` + * + * @see [RFC1122](https://www.rfc-editor.org/rfc/rfc1122) + */ + Loopback = 'loopback', + /** + * Equivalent to: `10.0.0.0/8` + * + * @see [RFC1918](https://www.rfc-editor.org/rfc/rfc1918) + */ + PrivateA = 'private-a', + /** + * Equivalent to: `172.16.0.0/12` + * + * @see [RFC1918](https://www.rfc-editor.org/rfc/rfc1918) + */ + PrivateB = 'private-b', + /** + * Equivalent to: `192.168.0.0/16` + * + * @see [RFC1918](https://www.rfc-editor.org/rfc/rfc1918) + */ + PrivateC = 'private-c', + /** + * Equivalent to: `192.0.2.0/24` + * + * @see [RFC5737](https://www.rfc-editor.org/rfc/rfc5737) + */ + TestNet1 = 'test-net-1', + /** + * Equivalent to: `198.51.100.0/24` + * + * @see [RFC5737](https://www.rfc-editor.org/rfc/rfc5737) + */ + TestNet2 = 'test-net-2', + /** + * Equivalent to: `203.0.113.0/24` + * + * @see [RFC5737](https://www.rfc-editor.org/rfc/rfc5737) + */ + TestNet3 = 'test-net-3', + /** + * Equivalent to: `169.254.0.0/16` + * + * @see [RFC3927](https://www.rfc-editor.org/rfc/rfc3927) + */ + LinkLocal = 'link-local', + /** + * Equivalent to: `224.0.0.0/4` + * + * @see [RFC5771](https://www.rfc-editor.org/rfc/rfc5771) + */ + Multicast = 'multicast', +} + +export type IPv4NetworkType = `${IPv4Network}`; + +const ipv4Networks: Record<IPv4Network, string> = { + [IPv4Network.Any]: '0.0.0.0/0', + [IPv4Network.Loopback]: '127.0.0.0/8', + [IPv4Network.PrivateA]: '10.0.0.0/8', + [IPv4Network.PrivateB]: '172.16.0.0/12', + [IPv4Network.PrivateC]: '192.168.0.0/16', + [IPv4Network.TestNet1]: '192.0.2.0/24', + [IPv4Network.TestNet2]: '198.51.100.0/24', + [IPv4Network.TestNet3]: '203.0.113.0/24', + [IPv4Network.LinkLocal]: '169.254.0.0/16', + [IPv4Network.Multicast]: '224.0.0.0/4', +}; + /** * Module to generate internet related entries. * @@ -485,15 +562,100 @@ export class InternetModule extends ModuleBase { /** * Generates a random IPv4 address. * + * @param options The optional options object. + * @param options.cidrBlock The optional CIDR block to use. Must be in the format `x.x.x.x/y`. Defaults to `'0.0.0.0/0'`. + * * @example * faker.internet.ipv4() // '245.108.222.0' + * faker.internet.ipv4({ cidrBlock: '192.168.0.0/16' }) // '192.168.215.224' * * @since 6.1.1 */ - ipv4(): string { - return Array.from({ length: 4 }, () => this.faker.number.int(255)).join( - '.' - ); + ipv4(options?: { + /** + * The optional CIDR block to use. Must be in the format `x.x.x.x/y`. + * + * @default '0.0.0.0/0' + */ + cidrBlock?: string; + }): string; + /** + * Generates a random IPv4 address. + * + * @param options The optional options object. + * @param options.network The optional network to use. This is intended as an alias for well-known `cidrBlock`s. Defaults to `'any'`. + * + * @example + * faker.internet.ipv4() // '245.108.222.0' + * faker.internet.ipv4({ network: 'private-a' }) // '10.199.154.205' + * + * @since 6.1.1 + */ + ipv4(options?: { + /** + * The optional network to use. This is intended as an alias for well-known `cidrBlock`s. + * + * @default 'any' + */ + network?: IPv4NetworkType; + }): string; + /** + * Generates a random IPv4 address. + * + * @param options The optional options object. + * @param options.cidrBlock The optional CIDR block to use. Must be in the format `x.x.x.x/y`. Defaults to `'0.0.0.0/0'`. + * @param options.network The optional network to use. This is intended as an alias for well-known `cidrBlock`s. Defaults to `'any'`. + * + * @example + * faker.internet.ipv4() // '245.108.222.0' + * faker.internet.ipv4({ cidrBlock: '192.168.0.0/16' }) // '192.168.215.224' + * faker.internet.ipv4({ network: 'private-a' }) // '10.199.154.205' + * + * @since 6.1.1 + */ + ipv4( + options?: + | { + /** + * The optional CIDR block to use. Must be in the format `x.x.x.x/y`. + * + * @default '0.0.0.0/0' + */ + cidrBlock?: string; + } + | { + /** + * The optional network to use. This is intended as an alias for well-known `cidrBlock`s. + * + * @default 'any' + */ + network?: IPv4NetworkType; + } + ): string; + ipv4( + options: { cidrBlock?: string; network?: IPv4NetworkType } = {} + ): string { + const { network = 'any', cidrBlock = ipv4Networks[network] } = options; + + if (!/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\/\d{1,2}$/.test(cidrBlock)) { + throw new FakerError( + `Invalid CIDR block provided: ${cidrBlock}. Must be in the format x.x.x.x/y.` + ); + } + + const [ipText, subnet] = cidrBlock.split('/'); + const subnetMask = 0xffffffff >>> Number.parseInt(subnet); + const [rawIp1, rawIp2, rawIp3, rawIp4] = ipText.split('.').map(Number); + const rawIp = (rawIp1 << 24) | (rawIp2 << 16) | (rawIp3 << 8) | rawIp4; + const networkIp = rawIp & ~subnetMask; + const hostOffset = this.faker.number.int(subnetMask); + const ip = networkIp | hostOffset; + return [ + (ip >>> 24) & 0xff, + (ip >>> 16) & 0xff, + (ip >>> 8) & 0xff, + ip & 0xff, + ].join('.'); } /** |
