Essential utility functions and classes for TypeScript/JavaScript applications including JSON handling, MIME data management, promise delegation, secure tokens, and cross-platform random number generation.
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Cross-platform random number generation with cryptographically strong fallbacks and unified API across browser and Node.js environments. Provides secure random bytes generation with automatic platform detection and fallback mechanisms.
Provides cryptographically strong random number generation with automatic platform detection and fallback.
/**
* The namespace for random number related functionality.
*/
namespace Random {
/**
* A function which generates random bytes.
*
* @param buffer - The `Uint8Array` to fill with random bytes.
*
* Notes:
* A cryptographically strong random number generator will be used if
* available. Otherwise, `Math.random` will be used as a fallback for
* randomness.
*
* The following RNGs are supported, listed in order of precedence:
* - `window.crypto.getRandomValues` (Modern browsers)
* - `window.msCrypto.getRandomValues` (IE 11)
* - `require('crypto').randomFillSync` (Node.js 7+)
* - `require('crypto').randomBytes` (Node.js 0.10+)
* - `Math.random` (Fallback)
*/
const getRandomValues: (buffer: Uint8Array) => void;
}Internal fallback implementation using Math.random for environments without crypto support.
/**
* Fallback random values generator using Math.random
* @param buffer - The Uint8Array to fill with pseudo-random bytes
*/
function fallbackRandomValues(buffer: Uint8Array): void;Usage Examples:
import { Random } from "@lumino/coreutils";
// Generate random bytes
const buffer = new Uint8Array(16);
Random.getRandomValues(buffer);
console.log(buffer); // Uint8Array with random values
// Generate random numbers
const randomBytes = new Uint8Array(4);
Random.getRandomValues(randomBytes);
// Convert to random integer (0 to 255 for each byte)
const randomInt = randomBytes[0];
console.log("Random integer (0-255):", randomInt);
// Generate random float (0 to 1)
const floatBytes = new Uint8Array(4);
Random.getRandomValues(floatBytes);
const randomFloat = (floatBytes[0] << 24 | floatBytes[1] << 16 | floatBytes[2] << 8 | floatBytes[3]) / 0x100000000;
console.log("Random float (0-1):", randomFloat);Secure Random Tokens:
import { Random } from "@lumino/coreutils";
function generateSecureToken(length: number = 32): string {
const buffer = new Uint8Array(length);
Random.getRandomValues(buffer);
// Convert to hexadecimal string
return Array.from(buffer)
.map(b => b.toString(16).padStart(2, '0'))
.join('');
}
// Usage
const sessionToken = generateSecureToken(16); // 32 character hex string
const apiKey = generateSecureToken(32); // 64 character hex string
console.log("Session token:", sessionToken);
console.log("API key:", apiKey);Random String Generation:
import { Random } from "@lumino/coreutils";
function generateRandomString(length: number, charset: string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'): string {
const buffer = new Uint8Array(length);
Random.getRandomValues(buffer);
let result = '';
for (let i = 0; i < length; i++) {
result += charset[buffer[i] % charset.length];
}
return result;
}
// Usage
const randomPassword = generateRandomString(12);
const randomId = generateRandomString(8, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789');
const randomSlug = generateRandomString(10, 'abcdefghijklmnopqrstuvwxyz0123456789');
console.log("Random password:", randomPassword);
console.log("Random ID:", randomId);
console.log("Random slug:", randomSlug);Secure Random Numbers:
import { Random } from "@lumino/coreutils";
function getRandomInt(min: number, max: number): number {
const range = max - min + 1;
const buffer = new Uint8Array(4);
// Generate random bytes until we get a value in range
// This prevents modulo bias
let result;
do {
Random.getRandomValues(buffer);
result = (buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3]) >>> 0;
} while (result >= Math.floor(0x100000000 / range) * range);
return min + (result % range);
}
function getRandomFloat(min: number = 0, max: number = 1): number {
const buffer = new Uint8Array(4);
Random.getRandomValues(buffer);
const randomValue = (buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3]) >>> 0;
return min + (randomValue / 0x100000000) * (max - min);
}
// Usage
const randomDiceRoll = getRandomInt(1, 6); // 1-6
const randomIndex = getRandomInt(0, 99); // 0-99
const randomPrice = getRandomFloat(10.0, 100.0); // 10.0-100.0
console.log("Dice roll:", randomDiceRoll);
console.log("Random index:", randomIndex);
console.log("Random price:", randomPrice.toFixed(2));Cryptographic Salt Generation:
import { Random } from "@lumino/coreutils";
function generateSalt(length: number = 16): Uint8Array {
const salt = new Uint8Array(length);
Random.getRandomValues(salt);
return salt;
}
function saltToHex(salt: Uint8Array): string {
return Array.from(salt)
.map(b => b.toString(16).padStart(2, '0'))
.join('');
}
function saltToBase64(salt: Uint8Array): string {
// Convert to base64 (simple implementation)
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
let result = '';
for (let i = 0; i < salt.length; i += 3) {
const a = salt[i];
const b = salt[i + 1] || 0;
const c = salt[i + 2] || 0;
const bitmap = (a << 16) | (b << 8) | c;
result += chars[(bitmap >> 18) & 63];
result += chars[(bitmap >> 12) & 63];
result += i + 1 < salt.length ? chars[(bitmap >> 6) & 63] : '=';
result += i + 2 < salt.length ? chars[bitmap & 63] : '=';
}
return result;
}
// Usage
const salt = generateSalt(16);
const saltHex = saltToHex(salt);
const saltBase64 = saltToBase64(salt);
console.log("Salt (raw):", salt);
console.log("Salt (hex):", saltHex);
console.log("Salt (base64):", saltBase64);Random Array Shuffling:
import { Random } from "@lumino/coreutils";
function shuffleArray<T>(array: T[]): T[] {
const shuffled = [...array];
for (let i = shuffled.length - 1; i > 0; i--) {
// Generate random index using secure random
const buffer = new Uint8Array(4);
Random.getRandomValues(buffer);
const randomValue = (buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3]) >>> 0;
const j = randomValue % (i + 1);
// Swap elements
[shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]];
}
return shuffled;
}
function getRandomElement<T>(array: T[]): T {
const buffer = new Uint8Array(4);
Random.getRandomValues(buffer);
const randomValue = (buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3]) >>> 0;
const index = randomValue % array.length;
return array[index];
}
// Usage
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const shuffledNumbers = shuffleArray(numbers);
console.log("Original:", numbers);
console.log("Shuffled:", shuffledNumbers);
const colors = ['red', 'blue', 'green', 'yellow', 'purple'];
const randomColor = getRandomElement(colors);
console.log("Random color:", randomColor);The Random namespace automatically detects the available cryptographic APIs:
window.crypto.getRandomValues()window.msCrypto.getRandomValues()Math.random() if crypto APIs unavailablecrypto.randomFillSync()crypto.randomBytes()Math.random() if crypto module unavailableMath.random() implementation is not cryptographically secure