Skip to content

Instantly share code, notes, and snippets.

@almic
Created February 16, 2018 01:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save almic/7007eafe54e44839635bfb8ce0b6942e to your computer and use it in GitHub Desktop.
Save almic/7007eafe54e44839635bfb8ce0b6942e to your computer and use it in GitHub Desktop.
A Node.js cryptographically secure pseudo-random number generator
const crypto = require('crypto')
function csprng(min, max) {
// Some credit to https://github.com/joepie91/node-random-number-csprng
/* Careful! This doesn't work with large ranges. Specifically, don't use
* this with ranges larger than 2^32 - 1 */
const range = max - min
if (range >= Math.pow(2, 32))
console.log("Warning! Range is too large.")
var tmp = range
var bitsNeeded = 0
var bytesNeeded = 0
var mask = 1
while (tmp > 0) {
if (bitsNeeded % 8 === 0) bytesNeeded += 1
bitsNeeded += 1
mask = mask << 1 | 1
tmp = tmp >>> 1
}
const randomBytes = crypto.randomBytes(bytesNeeded)
var randomValue = 0
for (var i = 0; i < bytesNeeded; i++) {
randomValue |= randomBytes[i] << 8 * i
}
randomValue = randomValue & mask;
if (randomValue <= range) {
return min + randomValue
} else {
return csprng(min, max)
}
}
// Test
var i = 1000000
const s = i
var num = 0
var a = 0
var b = 0
while (i > 0) {
num = csprng(0, 1)
if (num === 0)
a++;
else if (num === 1)
b++;
else {
console.log("Got strange number: " + num)
break
}
i--
}
console.log("0: " + a)
console.log("1: " + b)
console.log("Deviation: " + (Math.abs(a - b) / s) + " (smaller is probably better)")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment