Skip to content

@absoluteui/helpers/random

Crypto-backed random numbers, picks, shuffles, UUID v4/v7, IDs, passwords, and a seeded generator for tests.

import { ... } from '@absoluteui/helpers/random';

Random values from the platform’s cryptographic generator (crypto.getRandomValues): UUIDs, URL-safe ids, tokens, passwords, one-time codes, picks, and shuffles, all without modulo bias. For tests, demos, and reproducible sample data, createSeededRandom gives the same sequence for the same seed; it is not safe for secrets. The Helpers and services guide lists the security rules.

uuidV7 ids start with a millisecond timestamp, so they sort by creation time and index well in databases; createUuidV7Generator also keeps ids created in the same millisecond in order. randomId makes short URL-safe ids.

import { createUuidV7Generator, isUuid, randomId, uuidV7, uuidV7Timestamp } from '@absoluteui/helpers/random';
const id = uuidV7(); // e.g. '01922e6a-7c3b-7d4e-9f12-4c1d2e3f4a5b'
isUuid(id, 7); // => true
uuidV7Timestamp(uuidV7(Date.UTC(2026, 9, 5))); // => 1791158400000
const nextId = createUuidV7Generator();
const batch = [nextId(), nextId(), nextId()];
batch.join() === [...batch].sort().join(); // => true
randomId(12).length; // => 12

How do I generate a temporary password and a one-time code?

Section titled “How do I generate a temporary password and a one-time code?”

generatePassword guarantees at least one character from each enabled class; excludeAmbiguous drops look-alikes such as l, 1, O, and 0 for passwords read aloud or from paper. Deliver them over a secure channel and never log them.

import { generatePassword, randomOtp, randomString } from '@absoluteui/helpers/random';
const temp = generatePassword({ length: 14, excludeAmbiguous: true }); // e.g. 'q7G#mT2x!R4bNw'
[temp.length, /[a-z]/.test(temp), /[A-Z]/.test(temp), /[0-9]/.test(temp), /[Il1O0o]/.test(temp)]; // => [14, true, true, true, false]
const otp = randomOtp(6); // e.g. '042917'
/^[0-9]{6}$/.test(otp); // => true
randomString(32, { charset: 'hex' }).length; // => 32

How do I use repeatable randomness in tests and demo data?

Section titled “How do I use repeatable randomness in tests and demo data?”

Seed createSeededRandom with a number or string; the same seed yields the same values on every run and in every browser, so snapshots and screenshots stay stable.

import { createSeededRandom } from '@absoluteui/helpers/random';
const depts = ['Finance', 'HR', 'IT', 'Sales'];
function demoEmployees(seed: string) {
const rng = createSeededRandom(seed);
return Array.from({ length: 3 }, (_, i) => ({ id: `E-${i + 1}`, dept: rng.pick(depts), salary: rng.int(40, 90) * 1000 }));
}
JSON.stringify(demoEmployees('hrms-demo')) === JSON.stringify(demoEmployees('hrms-demo')); // => true
JSON.stringify(demoEmployees('hrms-demo')) === JSON.stringify(demoEmployees('other')); // => false

How do I pick reviewers or a random sample?

Section titled “How do I pick reviewers or a random sample?”

sample picks k distinct items and shuffle returns a shuffled copy; randomPickWeighted favours some options, for example spreading audits by team size.

import { randomPickWeighted, sample, shuffle } from '@absoluteui/helpers/random';
const reviewers = ['Maya', 'Omar', 'Lin', 'Sam', 'Ada'];
const panel = sample(reviewers, 2); // e.g. ['Lin', 'Maya']
new Set(panel).size; // => 2
shuffle(reviewers).length; // => 5
randomPickWeighted(['Finance', 'HR'], [1, 0]); // => 'Finance'

Impossible requests throw instead of returning a weaker result:

import { generatePassword, sample } from '@absoluteui/helpers/random';
sample(['Maya', 'Omar'], 3); // => throws HLP_RANDOM_SAMPLE_SIZE
generatePassword({ lower: false, upper: false, digits: false, symbols: false }); // => throws HLP_RANDOM_PASSWORD

Never use createSeededRandom or Math.random for tokens, passwords, or ids that must be unguessable.

createUuidV7Generator

Returns a UUID v7 generator that is strictly monotonic (RFC 9562 the specification method 1): within one millisecond, or when the clock moves backwards, the 12-bit rand_a field is used as a counter.

function createUuidV7Generator(clock?: () => number): () => string;

Example:

const next = createUuidV7Generator(); next() < next() // => true

generatePassword

Password meeting a character-class policy: minEach characters from every enabled class, the rest from their union, then an unbiased shuffle.

function generatePassword(options?: PasswordOptions): string;

Example:

const pw = generatePassword({ length: 20, symbols: false }); // e.g. 'q7GmT2xkR4bNw9LpZs3H'
pw.length; // => 20

isUuid

True for an RFC 9562 UUID string (versions 1-8, variant 10xx), optionally of a given version. Without a version, the nil and max UUIDs are also accepted.

function isUuid(value: unknown, version?: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8): boolean;

Example:

isUuid('01922e6a-7c3b-7d4e-9f12-0123456789ab', 7) // => true

randomBool

true with the given probability (default 0.5).

function randomBool(probability?: number): boolean;

Example:

randomBool(0.1); // e.g. false (true about 10% of the time)
randomBool(1); // => true

randomBytes

Cryptographically random bytes (chunked past the 64 KiB getRandomValues limit).

function randomBytes(length: number): Uint8Array<ArrayBuffer>;

Example:

randomBytes(16).length; // => 16

randomFloat

Uniform float in [min, max) with 53 bits of randomness.

function randomFloat(min?: number, max?: number): number;

Example:

const pct = randomFloat(0, 100); // e.g. 42.1937
pct >= 0 && pct < 100; // => true

randomId

Unbiased random id (nanoid-style mask and rejection). Default: 21 URL-safe characters (~126 bits).

function randomId(length?: number, alphabet?: string): string;

Example:

randomId(); // e.g. 'V1StGXR8_Z5jdHi6B-myT'
randomId(8, '0123456789abcdef').length; // => 8

randomInt

Uniform integer in [min, max] (inclusive); the range may span up to 2^53 values.

function randomInt(min: number, max: number): number;

Example:

const roll = randomInt(1, 6); // e.g. 4
roll >= 1 && roll <= 6 && Number.isInteger(roll); // => true

randomOtp

Numeric one-time code with uniformly random digits (leading zeros kept), 4-12 digits.

function randomOtp(digits?: number): string;

Example:

const code = randomOtp(); // e.g. '042917'
/^[0-9]{6}$/.test(code); // => true

randomPick

Uniformly chosen element, or undefined for an empty array. (Named randomPick so it does not clash with the object module’s pick.)

function randomPick<T>(items: readonly T[]): T | undefined;

Example:

randomPick(['red', 'green', 'blue']); // e.g. 'green'
randomPick([]); // => undefined

randomPickWeighted

Element chosen with probability proportional to its weight. Weights must be finite and non-negative with a positive total. undefined for empty input.

function randomPickWeighted<T>(items: readonly T[], weights: readonly number[]): T | undefined;

Example:

randomPickWeighted(['common', 'rare'], [9, 1]); // e.g. 'common' (90% of the time)
randomPickWeighted(['common', 'rare'], [1, 0]); // => 'common'

randomString

Unbiased random string from a preset or custom character set.

function randomString(length: number, options?: RandomStringOptions): string;

Example:

const token = randomString(8, { charset: 'hex' }); // e.g. '9f86d081'
/^[0-9a-f]{8}$/.test(token); // => true

sample

k distinct elements in random order (partial Fisher-Yates on a copy). Throws when k > length.

function sample<T>(items: readonly T[], k: number): T[];

Example:

const picked = sample([1, 2, 3, 4, 5], 2); // e.g. [4, 1]
new Set(picked).size; // => 2
sample([1, 2], 3); // => throws HLP_RANDOM_SAMPLE_SIZE

shuffle

Shuffled copy (unbiased Fisher-Yates); the input is not modified.

function shuffle<T>(items: readonly T[]): T[];

Example:

const deck = [1, 2, 3];
const mixed = shuffle(deck); // e.g. [3, 1, 2]
[...mixed].sort(); // => [1, 2, 3]
deck; // => [1, 2, 3] // input unchanged

shuffleInPlace

Shuffles items in place and returns it.

function shuffleInPlace<T>(items: T[]): T[];

Example:

const deck = ['A', 'K', 'Q', 'J'];
shuffleInPlace(deck) === deck; // => true
deck; // e.g. ['Q', 'A', 'J', 'K']

uuidV4

Random UUID version 4 (crypto.randomUUID when available, e.g. in secure contexts).

function uuidV4(): string;

Example:

const id = uuidV4(); // e.g. '3b241101-e2bb-4255-8caf-4136c566a962'
isUuid(id, 4); // => true

uuidV7

Time-ordered UUID version 7 (RFC 9562): 48-bit Unix ms timestamp, then 74 random bits. Stateless: two ids in the same millisecond are unordered; use createUuidV7Generator for strict order.

function uuidV7(timestamp?: number): string;

Example:

uuidV7(); // e.g. '01922e6a-7c3b-7d4e-9f12-4c1d2e3f4a5b'
uuidV7(1700000000000).slice(0, 13); // => '018bcfe5-6800'

uuidV7Timestamp

Millisecond timestamp embedded in a UUID v7, or undefined for other strings.

function uuidV7Timestamp(uuid: string): number | undefined;

Example:

uuidV7Timestamp(uuidV7(1700000000000)) // => 1700000000000

AMBIGUOUS_CHARACTERS

Characters dropped by generatePassword({ excludeAmbiguous: true }).

const AMBIGUOUS_CHARACTERS = "Il1|O0o`'\"";

MAX_RANDOM_BYTES

Largest randomBytes request.

const MAX_RANDOM_BYTES: number;

MAX_RANDOM_LENGTH

Longest randomId / randomString / generatePassword result.

const MAX_RANDOM_LENGTH = 65536;

URL_ALPHABET

URL-safe 64-character alphabet used by randomId.

const URL_ALPHABET = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";

PasswordOptions

interface PasswordOptions {
readonly length?: number;
readonly lower?: boolean;
readonly upper?: boolean;
readonly digits?: boolean;
readonly symbols?: boolean | string;
readonly excludeAmbiguous?: boolean;
readonly minEach?: number;
}

RandomStringOptions

interface RandomStringOptions {
readonly charset?: keyof typeof CHARSETS;
readonly alphabet?: string;
}

createSeededRandom

xoshiro128** generator seeded through splitmix32 from a number or string. NOT for security: output is predictable from the seed or a few outputs.

function createSeededRandom(seed: number | string): SeededRandom;

Example:

const a = createSeededRandom('demo');
const b = createSeededRandom('demo');
a.int(1, 6) === b.int(1, 6); // => true // same seed, same sequence
a.shuffle([1, 2, 3, 4, 5]); // => [5, 2, 4, 1, 3] // identical on every run for this seed

SeededRandom

Seeded, NON-cryptographic generator returned by createSeededRandom.

interface SeededRandom {
next(): number;
nextUint32(): number;
int(min: number, max: number): number;
float(min?: number, max?: number): number;
bool(probability?: number): boolean;
pick<T>(items: readonly T[]): T | undefined;
shuffle<T>(items: readonly T[]): T[];
}