Created
February 16, 2018 01:09
-
-
Save almic/7007eafe54e44839635bfb8ce0b6942e to your computer and use it in GitHub Desktop.
A Node.js cryptographically secure pseudo-random number generator
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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