Research
Security News
Malicious npm Packages Inject SSH Backdoors via Typosquatted Libraries
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
Randy is a utility module inspired by Python's very handy standard module "random". It contains a PRNG and useful randomness functions.
All functions are based on a JavaScript implementation of
WELL-1024a,
with up to 53-bit precision. The reason for this is that the built-in
Math.random()
function is
implementation-dependent
and therefore of very limited usefulness, as you risk running into
crappy implementations. Even the V8 engine (used by Node.js) only
provides 32-bit entropy, and is based on the platform-dependent C++
rand()
function.
var a = randy.randInt(100);
// a == 42
var d = randy.shuffle(["J spades", "K hearts", "10 hearts"]);
// d == [ "K hearts", "J spades", "10 hearts" ]
var c = randy.choice(["heads", "tails"]);
// c == "heads"
## Download
npm install randy
### In the Browser
Download and include as a <script>
. The module will be available as
the global object randy
.
Development: randy.js - 12Kb Uncompressed
Production: randy.min.js - 3.5Kb Minified
Example
<img id="computerHandImg">
<script src="randy.min.js"></script>
<script>
var h = document.getElementById("computerHandImg");
h.src = randy.choice([
"/img/rock",
"/img/paper",
"/img/kitten"
]);
</script>
All the above randomness functions use 32-bit precision if possible, but will use 53-bit precision if they need to go outside the 32-bit range.
The randomness functions are also available in always-53-bit-precision
versions, under the good
namespace. If you're working with values
over 65536 or so, imbalances of 0.01% will start to creep in, and a
higher precision will reduce this problem.
These functions take about 35% longer to run than the ones available
directly under randy
.
Example
// Generate example salary between 1,000,000 and 5,000,000
// with values clustering around 2,000,000.
var salary = randy.good.triangular(1000000, 5000000, 2000000);
The randomness functions are also available in maximally uniform
versions, under the best
namespace.
Random integer calculations in the randy
and randy.good
functions
are done via a modulo of a large random unsigned integer. This will
slightly favour lower numbers, but it is fast, and good enough for
most use cases. However, if you wish to avoid this imbalance, you can
use these functions.
These functions take on average 110% longer to run than the ones
available directly under randy
.
Example
var numbers = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
13, 14, 15, 16, 17, 18, 19, 20, 21, 22 ];
var lottery = randy.best.sample(numbers, 7);
Returns a random integer i
such that min <= i < max
.
If step
is provided, then additionally (i - min) % step = 0
.
Return value is based on a random 32-bit integer.
If max >= 2^32
, will call good.getInt()
, which goes up to
2^53.
Arguments
Example
console.log("Rolling the dice:");
var d1 = randy.randInt(1, 7);
var d2 = randy.randInt(1, 7);
console.log(d1 + " + " + d2 + " = " + (d1 + d2));
if (d1 + d2 == 2)
console.log("Snake eyes!");
Returns a randomly chosen element from the array arr.
Throws an exception if arr is empty.
Arguments
Example
var breakfast = randy.choice(["whisky", "bacon", "panic"]);
console.log("Good morning! Enjoy some " + breakfast + "!");
// Set direction vector for a ghost from Pac-Man.
ghost.currentDirection = randy.choice([
{x:0, y:-1}, {x:1, y:0}, {x:0, y:1}, {x:-1, y:0}
]);
Returns a shuffled copy of arr. Returned array contains the exact same elements as arr, and equally many elements, but in a new order.
Uses the Fisher-Yates algorithm, aka the Knuth Shuffle.
Arguments
Example
var runners = ["Andy", "Bob", "Clarence", "David"];
var startingOrder = randy.shuffle(runners);
Shuffles the array arr. A more memory-efficient version of shuffle.
Uses the Fisher-Yates algorithm, aka the Knuth Shuffle.
Arguments
Example
// Reorder elements at random until they happen to be sorted.
function bogosort (arr) {
while (true) {
randy.shuffleInplace(arr);
var sorted = true;
for (var i=0; i<arr.length-1; i++)
sorted = sorted && (arr[i] < arr[i+1]);
if (sorted)
return;
}
}
// Create new draw deck from card discard pile.
if (deck.length == 0) {
deck = discardPile.splice(0);
randy.shuffleInplace(deck);
}
Returns an array of length count, containing unique elements chosen from the array population. Like a raffle draw.
Mathematically equivalent to shuffle(population).slice(0, count)
, but
more efficient. Catches fire if count > population.length
.
Arguments
Example
// Raffle draw for 3 bottles of wine. Cindy has bought 2 tickets.
var raffleTickets = ["Alice", "Beatrice", "Cindy", "Cindy", "Donna"];
var winners = randy.sample(raffleTickets, 3);
console.log("The winners are: " + winners.join(", "));
Returns a floating point number n, such that 0.0 <= n < 1.0
.
Exactly as uniform()
, but provided for familiarity.
Returns a floating point number n, such that min <= n < max
.
Arguments
Example
// Torpedo guidance system.
var heading = randy.uniform(360.0);
// Random event repeating every 1-5 minutes.
function flashLightning () {
flash();
var delayNext = randy.uniform(1.0 * 60000, 5.0 * 60000);
setTimeout(flashLightning, delayNext);
}
The triangular distribution is typically used as a subjective description of a population for which there is only limited sample data, and especially in cases where the relationship between variables is known but data is scarce (possibly because of the high cost of collection). It is based on a knowledge of the minimum and maximum and an "inspired guess" as to the modal value.
Arguments
Example
// Generate customer test data. Customers are aged 18 to 40, but
// most of them are in their twenties. Their income is between
// 40000-150000 Hyrulean Rupees per year, but typically around
// 60000.
for (i=0; i<1000; i++) {
db.insertCustomer({
name: "Bruce",
birthYear: Math.floor( randy.triangular(1972, 1990, 1983) ),
income: randy.triangular(40000, 150000, 60000)
});
}
Returns a random integer of bit width n, where n <= 53
.
Arguments
Example
// A perfect distribution function, which rejects overflow values
// instead of squeezing them into the desired range by use of modulo.
function perfectInt (max) {
if (max == 0)
return 0;
var log2 = 0;
var mult = 1;
while (mult < max) {
log2 += 1;
mult *= 2;
}
while (false == false) {
var r = randy.getRandBits(log2);
if (r < max)
return r;
}
}
Returns a JavaScript object representing the current state of the generator.
This object can be used as a parameter to setState()
.
Sets the generator to a specific state, allowing for replay of random values.
Arguments
getState()
.Example
This will roll a pair of dice, reset the generator state, and roll the dice again with the exact same output.
var state = randy.getState();
console.log("Rolling the dice:");
var d1 = randy.randInt(1, 7);
var d2 = randy.randInt(1, 7);
console.log(d1 + " + " + d2 + " = " + (d1 + d2));
console.log("Instant replay:");
randy.setState(state);
d1 = randy.randInt(1, 7);
d2 = randy.randInt(1, 7);
console.log(d1 + " + " + d2 + " = " + (d1 + d2));
### instance ()
### instance (state)
Creates a separate randy
instance, for those use cases where a
global object is a bad fit. The instance has the same functions as
the global object.
If no state
parameter is given, the new instance will be initialized
randomly.
Calling this will not affect the generator state.
Arguments
getState()
.Example
Create two instances, one a copy of the global object. Sync the
copies to the original randy
state.
var origState = randy.getState();
var r1 = randy.instance(origState);
var r2 = randy.instance();
console.log(randy.randInt(50), r1.randInt(50), r2.randInt(50)); // 34 34 17
console.log(randy.randInt(50), r1.randInt(50), r2.randInt(50)); // 12 12 4
r1.setState(origState);
r2.setState(origState);
console.log(randy.randInt(50), r1.randInt(50), r2.randInt(50)); // 15 34 34
console.log(randy.randInt(50), r1.randInt(50), r2.randInt(50)); // 36 12 12
No functions rely on this
, so it's safe to e.g. assign
randy.good.randInt
to a variable or pass it around as a
parameter.
Due to floating point rounding, functions returning floating point values may extremely rarely tangent the upper bound.
Maximum integer range is 2^53 = 9007199254740992. This is the maximum integer available in JavaScript without losing precision. Any calls requiring a larger range than this, explicitly or implicitly, will not yield correct results.
FAQs
Random utilities based on WELL-1024a PRNG.
The npm package randy receives a total of 11,277 weekly downloads. As such, randy popularity was classified as popular.
We found that randy demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
Security News
MITRE's 2024 CWE Top 25 highlights critical software vulnerabilities like XSS, SQL Injection, and CSRF, reflecting shifts due to a refined ranking methodology.
Security News
In this segment of the Risky Business podcast, Feross Aboukhadijeh and Patrick Gray discuss the challenges of tracking malware discovered in open source softare.