1

Using the following function, i'm able to generate random integers within a specific range:

function random_int(min, max) {
    min = Math.ceil(min);
    max = Math.floor(max);
    return Math.floor(Math.random() * (max - min + 1)) + min; //The maximum is inclusive and the minimum is inclusive 
}

so if we use random_int(0,2) we should expect to have the values 0,1 or 2 to be returned.

Tho, as some of you may already know, Math.random(); is not cryptographically secure. The reason i need unpredictable numbers is that I want to generate secure captchas as part of me learning how to use canvas and node.js. (Draw random lines and text, for example)

So i've been duckduckin' around the web for a solution, and found this:

const buf = crypto.randomBytes(256);
console.log(
  `${buf.length} bytes of random data: ${buf.toString('hex')}`);

Which does works, but it also returns letters and I have absolutely no idea of how to implement this random "number" generator in my existing function...

I've also read about some people attempting to create number generators from this function but i'd like you guy's feedback on this as "my own Cryptography.random() function" sounds like a red flag in crypto, apparently.

Thanks in advance!

-- EDIT --

Thanks to Andre Nel, here is my new function for random numbers! Big thanks to him.

const crypto = require("crypto"); //import crypto
var converter = require('hex2dec');

// Cryptographically secure random integer
function random_int_c(min, max) {
    const buf = crypto.randomBytes(1);

    var dec = converter.hexToDec(buf.toString('hex')).substring(0, 2);

    return Math.floor(Number("0."+dec) * (max - min + 1) + min);
}
danorton
  • 11,804
  • 7
  • 44
  • 52
keanu_reeves
  • 350
  • 1
  • 12
  • By accepting the answer below, you have already indicated that your question is resolved. You should not edit your question to include the answer that you selected. – Patrick Roberts Mar 12 '20 at 02:47
  • 1
    that should be posted as an answer, not edited as part of your question. You can still leave their answer accepted, but that content is not and should not be part of your question. – Patrick Roberts Mar 12 '20 at 03:36
  • The answer edited into the question if not correct, assuming that you care about the distribution of the random values. You generate one random byte (256 possible values) and then take the first 2 digits. So if the random value is below 100, every value is equally likely. However, if the random value is 100 or more, the truncated value is in the range [10, 25] and counts 10 times (6 times if it is 25). This means that the final factors 1.10 - 1.25 are 11 times more likely than any other factor, which heavily skews your distribution. – Vincent van der Weele Mar 01 '21 at 13:11
  • See this question for the correct approach: https://stackoverflow.com/q/51325338/2095090 – Vincent van der Weele Mar 01 '21 at 13:12

2 Answers2

0
// NodeJS -> test in -> https://repl.it/languages/nodejs

const crypto = require('crypto');
const buf = crypto.randomBytes(256);
console.log(`${buf.length} bytes of random data: ${buf.toString('hex')}`);

var converter = require('hex2dec');
var dec = converter.hexToDec(buf.toString('hex'));
console.log(`random number: ${dec}`);
Andre Nel
  • 432
  • 2
  • 9
0

Looks like crypto.randomInt is the way to go now.

sunknudsen
  • 6,356
  • 3
  • 39
  • 76