Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting random bytes to an integer range - how?

I'm trying to get a random integer within a range by reading from crypto.randomBytes().

Now, my problem is that I do not know how to read integers from that byte stream. I imagine generating a range is simply a matter of 'throwing away' the ints not in range.

Any ideas?

like image 702
Stephan Tual Avatar asked Apr 04 '13 20:04

Stephan Tual


3 Answers

To obtain a cryptographically secure and uniformly distributed value in the [0,1) interval (i.e. same as Math.random()) in NodeJS

const random = crypto.randomBytes(4).readUInt32LE() / 0x100000000;
console.log(random); //e.g. 0.9002735135145485

or in the Browser

const random = window.crypto.getRandomValues(new Uint32Array(1))[0] / 0x100000000;
console.log(random);
like image 159
gogo Avatar answered Nov 16 '22 06:11

gogo


You can get one 32 bit integer from crypto.randomBytes with the code below. If you need more than one you can ask for more bytes from crypto.randomBytes and then use substr to individually select and convert each integer.

crypto.randomBytes(4, function(ex, buf) {
  var hex = buf.toString('hex');
  var myInt32 = parseInt(hex, 16);
});

Having said that, you might want to just use Math.floor(Math.random() * maxInteger)

like image 16
Daniel Avatar answered Nov 16 '22 05:11

Daniel


const { randomInt } = await import('crypto');

const n = randomInt(1, 7);
console.log(`The dice rolled: ${n}`);

Now it is implemented in node itself https://nodejs.org/api/crypto.html#crypto_crypto_randomint_min_max_callback

like image 3
bFunc Avatar answered Nov 16 '22 06:11

bFunc