@alwatr/random
Version:
A lightweight utility library for generating random numbers, strings, UUIDs and more
8 lines (7 loc) • 9.35 kB
Source Map (JSON)
{
"version": 3,
"sources": ["../src/main.ts"],
"sourcesContent": ["import {getGlobalThis} from '@alwatr/global-this';\n\nconst globalThis = getGlobalThis();\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": []
}