random-tables-mcp
Version:
An MCP (Model Context Protocol) server for managing and rolling on random-table assets used in tabletop RPGs. Create, update, and roll on random tables with support for nested tables, weighted entries, and range-based results.
61 lines • 2.51 kB
JavaScript
import * as crypto from 'crypto';
/**
* Implementation of the RandomNumberGenerator interface using Node's crypto module.
* Provides cryptographically secure random numbers.
*/
export class CryptoRandomNumberGenerator {
/**
* Generates a cryptographically secure random number between min and max (inclusive).
* @param min The minimum value (inclusive).
* @param max The maximum value (inclusive).
* @returns A random number between min and max.
*/
getRandomNumber(min, max) {
// Ensure min is less than or equal to max
if (min > max) {
throw new Error('Min must be less than or equal to max');
}
// Handle special case where min equals max
if (min === max) {
return min;
}
// For floating point values between 0 and 1
if (min === 0 && max === 1) {
// Generate a random 32-bit unsigned integer and divide by 2^32
const buffer = crypto.randomBytes(4);
const randomValue = buffer.readUInt32LE(0) / 0x100000000;
return randomValue;
}
// For integer ranges, use randomInt which is more efficient
// randomInt is inclusive of min, exclusive of max+1
return crypto.randomInt(min, max + 1);
}
/**
* Gets a weighted random index based on the provided weights using
* cryptographically secure random number generation.
* @param weights An array of weights.
* @returns A random index, with probability proportional to the weights.
* @throws Error if the weights array is empty or contains non-positive values.
*/
getWeightedIndex(weights) {
if (weights.length === 0) {
throw new Error('Weights array cannot be empty');
}
if (weights.some(weight => weight <= 0)) {
throw new Error('All weights must be positive');
}
const totalWeight = weights.reduce((sum, weight) => sum + weight, 0);
// Generate a random value between 0 and totalWeight
const randomValue = this.getRandomNumber(0, 1) * totalWeight;
let cumulativeWeight = 0;
for (let i = 0; i < weights.length; i++) {
cumulativeWeight += weights[i];
if (randomValue < cumulativeWeight) {
return i;
}
}
// Fallback (should never happen with proper weights)
return weights.length - 1;
}
}
//# sourceMappingURL=crypto-random-number-generator.js.map