UNPKG

@alwatr/random

Version:

A lightweight utility library for generating random numbers, strings, UUIDs and more

8 lines (7 loc) 9.65 kB
{ "version": 3, "sources": ["../src/main.ts"], "sourcesContent": ["import {getGlobalThis} from '@alwatr/global-this';\nimport {packageTracer} from '@alwatr/package-tracer';\n\nconst globalThis = getGlobalThis();\n\n__dev_mode__: packageTracer.add(__package_name__, __package_version__);\n\n// Use the native crypto module when available for better randomness\nconst hasCrypto = typeof globalThis.crypto !== 'undefined';\n\n/**\n * Converts a Uint8Array or number array into a hexadecimal string representation.\n * Each byte is converted to a two-character hex string (padded with a leading zero if necessary)\n * and concatenated together to form a single string.\n *\n * @param bytes - The array of bytes to convert to hexadecimal\n * @returns A hexadecimal string representation of the input bytes\n *\n * @example\n * ```ts\n * // Using with Uint8Array\n * const bytes = new Uint8Array([10, 255, 0, 16]);\n * bytesToHex(bytes); // Returns \"0aff0010\"\n *\n * // Using with number array\n * const array = [171, 205, 3];\n * bytesToHex(array); // Returns \"abcd03\"\n * ```\n */\nexport function bytesToHex(bytes: number[] | Uint8Array): string {\n let result = '';\n for (const byte of bytes) {\n const hex = byte.toString(16);\n result += hex.length === 1 ? '0' + hex : hex;\n }\n return result;\n}\n\n/**\n * Returns a float random number between 0 and 1 (1 not included).\n *\n * Example:\n *\n * ```js\n * console.log(randNumber()); // 0.7124123\n * ```\n */\nexport function randNumber(): number {\n return Math.random();\n}\n\n/**\n * Generate a random float number between min and max (max not included).\n *\n * Example:\n *\n * ```js\n * console.log(randFloat(1, 10)); // somewhere between 1 and 10 (as float)\n * ```\n */\nexport function randFloat(min: number, max: number): number {\n return Math.random() * (max - min) + min;\n}\n\n/**\n * Generate a random integer number between min and max (max included).\n *\n * Example:\n *\n * ```js\n * console.log(randInteger(1, 10)); // somewhere between 1 and 10\n * ```\n */\nexport function randInteger(min: number, max: number): number {\n // Use Math.floor and add 1 to max for better distribution\n return Math.floor(randFloat(min, max + 1));\n}\n\n/**\n * Generate a random string with specified length.\n * The string will contain only characters from the characters list.\n * The length of the string will be between min and max (max included).\n * If max not specified, the length will be set to min.\n *\n * Example:\n *\n *```js\n * console.log(randString(6)); // something like 'Aab1V2'\n * console.log(randString(3, 6)); // random length between 3 and 6\n * console.log(randString(5, undefined, '01')); // binary string like '10101'\n * ```\n */\nexport function randString(\n minLength: number,\n maxLength: number = minLength,\n chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',\n): string {\n const length = maxLength === minLength ? minLength : randInteger(minLength, maxLength);\n if (length <= 0) return '';\n\n const charsLength = chars.length;\n\n let result = '';\n\n // Small optimization for short strings\n if (length <= 10) {\n for (let i = 0; i < length; i++) {\n result += chars.charAt(Math.floor(Math.random() * charsLength));\n }\n return result;\n }\n // else\n // For longer strings, use array join for better performance\n const resultArray = new Array(length);\n for (let i = 0; i < length; i++) {\n resultArray[i] = chars.charAt(Math.floor(Math.random() * charsLength));\n }\n return resultArray.join('');\n}\n\n/**\n * Generate a random integer between min and max with a step.\n *\n * Example:\n *\n * ```js\n * console.log(randStep(6, 10, 2)); // 6 or 8 or 10\n * ```\n */\nexport function randStep(min: number, max: number, step: number): number {\n if (step === 0) {\n return min; // Return min when step is 0 to avoid division by zero\n }\n const steps = Math.floor((max - min) / step);\n return min + randInteger(0, steps) * step;\n}\n\n/**\n * Shuffle an array in place using Fisher-Yates shuffle algorithm and return it.\n *\n * Example:\n *\n * ```js\n * const array = [1, 2, 3, 4, 5];\n * randShuffle(array);\n * console.log(array); // [2, 4, 3, 1, 5] (randomized)\n * ```\n */\nexport function randShuffle<T>(array: T[]): T[] {\n for (let i = array.length - 1; i > 0; i--) {\n const j = randInteger(0, i);\n [array[i], array[j]] = [array[j], array[i]];\n }\n return array;\n}\n\n/**\n * Choose a random item from an array.\n * Throws an error if the array is empty.\n *\n * Example:\n *\n * ```js\n * const array = [1, 2, 3, 4, 5];\n * console.log(randPick(array)); // one random element\n * ```\n */\nexport function randPick<T>(array: T[]): T {\n if (array.length === 0) throw new Error('Cannot pick from empty array');\n return array[randInteger(0, array.length - 1)];\n}\n\n/**\n * Fills a typed array with random integer values within the specified range.\n * The array is modified in place and also returned for chaining.\n *\n * @param array - The array to fill with random values (modified in place)\n * @param min - Minimum value (inclusive), defaults to 0\n * @param max - Maximum value (inclusive), defaults to 255\n * @returns The same array that was passed in (for chaining)\n *\n * @example\n * ```ts\n * // Fill a Uint8Array with random values (0-255)\n * randArray(new Uint8Array(10));\n *\n * // Fill with custom range\n * randArray(new Uint16Array(5), 1000, 2000); // Values between 1000-2000\n *\n * // Also works with number arrays\n * randArray(new Array<number>(8), -100, 100); // Values between -100 and 100\n * ```\n */\nexport function randArray<T extends number[] | Uint8Array | Uint16Array | Uint32Array>(array: T, min = 0, max = 255): T {\n for (let i = array.length - 1; i >= 0; i--) {\n array[i] = randInteger(min, max);\n }\n return array;\n}\n\n/**\n * Type alias for a UUID string.\n */\nexport type UUID = `${string}-${string}-${string}-${string}-${string}`;\n\n/**\n * Generate a random UUID (v4).\n *\n * Example:\n *\n * ```js\n * console.log(randUuid()); // \"a1b2c3d4-e5f6-47a8-b9c0-d1e2f3a4b5c6\"\n * ```\n */\nexport function randUuid(): UUID {\n if (hasCrypto && globalThis.crypto?.randomUUID) {\n return globalThis.crypto.randomUUID() as UUID;\n }\n\n // Fallback implementation\n const bytes = randArray(new Uint8Array(16));\n bytes[6] = (bytes[6] & 0x0f) | 0x40; // version 4\n bytes[8] = (bytes[8] & 0xbf) | 0x80; // variant RFC4122\n\n // prettier-ignore\n return `${\n bytesToHex(bytes.subarray(0, 4))\n }-${\n bytesToHex(bytes.subarray(4, 6))\n }-${\n bytesToHex(bytes.subarray(6, 8))\n }-${\n bytesToHex(bytes.subarray(8, 10))\n }-${\n bytesToHex(bytes.subarray(10, 16))\n }` as UUID;\n}\n\n/**\n * Generate a random boolean with specified probability of being true.\n *\n * Example:\n *\n * ```js\n * console.log(randBoolean()); // 50% chance of true\n * console.log(randBoolean(0.8)); // 80% chance of true\n * ```\n */\nexport function randBoolean(probability = 0.5): boolean {\n return Math.random() < probability;\n}\n\n/**\n * Generate a random hex color string.\n *\n * Example:\n *\n * ```js\n * console.log(randColor()); // \"#a1b2c3\"\n * ```\n */\nexport function randColor(): string {\n const bytes = randArray(new Array<number>(3));\n return `#${bytesToHex(bytes)}`;\n}\n"], "mappings": "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", "names": [] }