I am trying to generate exactly 6
random digits in Node.js, which needs to be cryptographically secure. Here is my code:
var crypto = require('crypto');
crypto.randomBytes(2, function(err, buffer) {
console.log(parseInt(buffer.toString('hex'), 16));
});
The problem is that the result from this can be 4
or 5
digits, because we are converting from hex to decimal. Is there a way to keep the cryptographically secure function randomBytes()
, but guarantee a 6 digit result?
2 bytes have a maximum value of 65535, so you will never get 6 digits if you only use 2 bytes.
Use 3 bytes instead and then reduce it to 6 digits using substr
:
var crypto = require('crypto');
crypto.randomBytes(3, function(err, buffer) {
console.log(parseInt(buffer.toString('hex'), 16).toString().substr(0,6));
});
Another solution would be to execute randomBytes
until you get a 6 digit value:
var crypto = require('crypto');
var secureVal = 0;
function generateSecureVal(cb) {
crypto.randomBytes(3, function(err, buffer) {
secureVal = parseInt(buffer.toString('hex'), 16);
if (secureVal > 999999 || secureVal < 100000) {
generateSecureVal(cb);
} else {
cb();
}
});
}
generateSecureVal(function(){
console.log(secureVal);
});
The problem with the above is that it could theoretically get stuck in a neverending loop, and it will most likely use way more CPU cycles than the first example.
A new function for doing this was added to Node v14.17
crypto.randomInt([min, ]max[, callback])
To get a 6 digit integer.
const crypto = require('crypto');
crypto.randomInt(100000, 999999, (err, n) => {
if (err) throw err;
console.log(`Random 6 digit integer: ${n}`);
});
Also per the documentation https://nodejs.org/api/crypto.html#cryptorandomintmin-max-callback you should also check that your min and max values are safe integers via:
Number.isSafeInteger()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With