hypermiler
hypermiler

Reputation: 2107

How to Generate a random number of fixed length using JavaScript?

I'm trying to generate a random number that must have a fixed length of exactly 6 digits.

I don't know if JavaScript has given below would ever create a number less than 6 digits?

Math.floor((Math.random()*1000000)+1);

I found this question and answer on StackOverflow here. But, it's unclear.

EDIT: I ran the above code a bunch of times, and Yes, it frequently creates numbers less than 6 digits. Is there a quick/fast way to make sure it's always exactly 6 digits?

Upvotes: 154

Views: 308342

Answers (27)

Tarlan Ziyadov
Tarlan Ziyadov

Reputation: 1

Might be useful

const randomCharacters = (length, type) => {
  let characters;


  if (type === 'string') {
    characters = 'abcdefghijklmnopqrstuvwxyz';
  }


  if (type === 'number') {
    characters = '123456789';
  }


  let result = '';
  const charactersLength = characters.length;

  for (let i = 0; i < length; i++) {
    result += characters.charAt(Math.floor(Math.random() * charactersLength));
  }
  return result;
}

console.log(randomCharacters(5, 'number'));

Upvotes: -3

mjs
mjs

Reputation: 22357


Only fully reliable answer that offers full randomness, without loss. The other ones prior to this answer all looses out depending on how many characters you want. The more you want, the more they lose randomness.

They achieve it by limiting the amount of numbers possible preceding the fixed length.

So for instance, a random number of fixed length 2 would be 10 - 99. For 3, 100 - 999. For 4, 1000 - 9999. For 5 10000 - 99999 and so on. As can be seen by the pattern, it suggests 10% loss of randomness because numbers prior to that are not possible. Why?

For really large numbers ( 18, 24, 48 ) 10% is still a lot of numbers to loose out on.

function generate(n, chunks = 0, separator = ' ') {
    var add = 1, max = 12 - add;   // 12 is the min safe number Math.random() can generate without it starting to pad the end with zeros.
    
    var out;
    if ( n > max ) {
        out = generate(max) + generate(n - max);
    }
    else {
        max        = Math.pow(10, n+add);
        var min    = max/10; // Math.pow(10, n) basically
        var number = Math.floor( Math.random() * (max - min + 1) ) + min;
        
        out = ("" + number).substring(add);
    }
    
    if (chunks > 0 && n > chunks) {
        // Insert separator every chunks characters
        const instead = []; for (let i = 0; i < out.length; i++) {
            if (i > 0 && i % chunks === 0) instead.push(separator);
            instead.push(out[i]);
        }
        
        return instead.join('');
    }
    
    return out;
}

The generator allows for ~infinite length without lossy precision and with minimal performance cost.

Example:

generate(2)
"03"
generate(2)
"72"
generate(2)
"20"
generate(3)
"301"
generate(3)
"436"
generate(3)
"015"
generate(9, 3)
"134 456 890"
generate(9, 3, '|')
"134|456|890"

As you can see, even the zero are included initially which is an additional 10% loss just that, besides the fact that numbers prior to 10^n are not possible.

That is now a total of 20%.

Also, the other options have an upper limit on how many characters you can actually generate.

Example with cost:

var start = new Date(); var num = generate(1000); console.log('Time: ', new Date() - start, 'ms for', num)

Logs:

Time: 0 ms for 7884381040581542028523049580942716270617684062141718855897876833390671831652069714762698108211737288889182869856548142946579393971303478191296939612816492205372814129483213770914444439430297923875275475120712223308258993696422444618241506074080831777597175223850085606310877065533844577763231043780302367695330451000357920496047212646138908106805663879875404784849990477942580056343258756712280958474020627842245866908290819748829427029211991533809630060693336825924167793796369987750553539230834216505824880709596544701685608502486365633618424746636614437646240783649056696052311741095247677377387232206206230001648953246132624571185908487227730250573902216708727944082363775298758556612347564746106354407311558683595834088577220946790036272364740219788470832285646664462382109714500242379237782088931632873392735450875490295512846026376692233811845787949465417190308589695423418373731970944293954443996348633968914665773009376928939207861596826457540403314327582156399232931348229798533882278769760

More hardcore:

generate(100000).length === 100000 -> true

Upvotes: 43

KooiInc
KooiInc

Reputation: 122906

Here is a random number creator helper (function getRandomValues) using crypto.getRandomValues.

The function randomNrWithFixedLength in the next snippet creates random numbers with the fixed length [len].

See also

for (let i = 0; i < 10; i += 1) {
  console.log(randomNrWithFixedLength(6).toLocaleString());
}

function randomNrWithFixedLength(len) {
  len = len < 2 ? 2 : len;
  // first should be 1 - 9
  const first = getRandomValues({
    len: 1, 
    min: 0, 
    max: 10 });
  const residual = getRandomValues({
    len: len-1, 
    min: 0, 
    max: 10, 
    inclusive: {min: true} });
    
  return +[...first, ...residual].join(``);
}

function getRandomValues({ 
    len = 1, min, max, 
    inclusive = {max: false, min: false} } = {} ) {
  const chunkSize = 2**14;
  correctInputIfNecessary();
  
  if (len <= chunkSize) { return createArrayOfRandomValues(len); }

  let iterations = Math.floor(len / chunkSize);
  const remainder = len % chunkSize;
  const res = [];
  
  do { res.push(...createArrayOfRandomValues(chunkSize)); } 
  while (--iterations);
  
  remainder > 0 && res.push(...createArrayOfRandomValues(remainder));
  
  return res;

  function correctInputIfNecessary() {
    const MSI = Number.MAX_SAFE_INTEGER;
    inclusive.min = inclusive.min?.constructor !== Boolean 
      ? false : inclusive.min;
    inclusive.max = inclusive.max?.constructor !== Boolean 
      ? false : inclusive.max;
    len = len?.constructor !== Number || len < 1 || len > MSI 
      ? 1 : len;  
    min = +!inclusive.min + (min?.constructor !== Number || min < 0 
      ? 0 : min);
    max = +inclusive.max + (max?.constructor !== Number || max >= MSI 
      ? MSI - 1 : max);
  }

  function createArrayOfRandomValues(len) {
    return crypto.getRandomValues(new Uint32Array(len)).map( v =>
      Math.floor( min + ( v/2**32 * (max - min) ) ) );
  }
}
.as-console-wrapper {
    max-height: 100% !important;
}

Upvotes: 0

Kushagra Gour
Kushagra Gour

Reputation: 4966

parseInt(Math.random().toString().slice(2,Math.min(length+2, 18)), 10); 

18 is due to max digits in Math.random()

Update: This method has a few flaws:

  • Sometimes the number of digits might be lesser if it's left padded with zeroes.

Upvotes: -4

Arthur Grishin
Arthur Grishin

Reputation: 358

Based on link you've provided, right answer should be

Math.floor(Math.random()*899999+100000);

Math.random() returns float between 0 and 1, so minimum number will be 100000, max - 999999. Exactly 6 digits, as you wanted :)

Upvotes: 7

Kamil Kiełczewski
Kamil Kiełczewski

Reputation: 92367

short with arbitrary precision

below code ALWAYS generate string with n digits - solution in snippet use it

[...Array(n)].map(_=>Math.random()*10|0).join``

let gen = n=> [...Array(n)].map(_=>Math.random()*10|0).join``

// TEST: generate 6 digit number
// first number can't be zero - so we generate it separatley
let sixDigitStr = (1+Math.random()*9|0) + gen(5)
console.log( +(sixDigitStr) ) // + convert to num

Upvotes: 9

Puvipavan
Puvipavan

Reputation: 298

let length = 6;
("0".repeat(length) + Math.floor(Math.random() * 10 ** length)).slice(-length);

Math.random() - Returns floating point number between 0 - 1

10 ** length - Multiply it by the length so we can get 1 - 6 length numbers with decimals

Math.floor() - Returns above number to integer(Largest integer to the given number).

What if we get less than 6 digits number?

That's why you have to append 0s with it. "0".repeat() repeats the given string which is 0

So we may get more than 6 digits right? That's why we have to use "".slice() method. It returns the array within given indexes. By giving minus values, it counts from the last element.

Upvotes: 2

Nader
Nader

Reputation: 1

Generate a random number that will be 6 digits:

console.log(Math.floor(Math.random() * 900000));

Result = 500229

Generate a random number that will be 4 digits:

console.log(Math.floor(Math.random() * 9000));

Result = 8751

Upvotes: -1

I-EAT-DATA
I-EAT-DATA

Reputation: 229

You can use the below code to generate a random number that will always be 6 digits:

Math.random().toString().substr(2, 6)

Hope this works for everyone :)

Briefly how this works is Math.random() generates a random number between 0 and 1 which we convert to a string and using .toString() and take a 6 digit sample from said string using .substr() with the parameters 2, 6 to start the sample from the 2nd char and continue it for 6 characters.

This can be used for any length number.

If you want to do more reading on this here are some links to the docs to save you some googling:

Math.random(): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random

.toString(): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/toString

.substr(): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/substr

Upvotes: 22

Shantanu Kawale
Shantanu Kawale

Reputation: 88

const generate = n => String(Math.ceil(Math.random() * 10**n)).padStart(n, '0')
// n being the length of the random number.

Use a parseInt() or Number() on the result if you want an integer. If you don't want the first integer to be a 0 then you could use padEnd() instead of padStart().

Upvotes: 1

Stephen Yeung
Stephen Yeung

Reputation: 1

generate a random number that must have a fixed length of exactly 6 digits:

("000000"+Math.floor((Math.random()*1000000)+1)).slice(-6)

Upvotes: -1

Aaron Plocharczyk
Aaron Plocharczyk

Reputation: 2832

I use randojs to make the randomness simpler and more readable. you can pick a random int between 100000 and 999999 like this with randojs:

console.log(rando(100000, 999999));
<script src="https://randojs.com/1.0.0.js"></script>

Upvotes: 1

Ricki-BumbleDev
Ricki-BumbleDev

Reputation: 2256

In case you also want the first digit to be able to be 0 this is my solution:

const getRange = (size, start = 0) => Array(size).fill(0).map((_, i) => i + start);

const getRandomDigit = () => Math.floor(Math.random() * 10);

const generateVerificationCode = () => getRange(6).map(getRandomDigit).join('');

console.log(generateVerificationCode())

Upvotes: 0

Abraham Hamidi
Abraham Hamidi

Reputation: 13799

console.log(Math.floor(100000 + Math.random() * 900000));

Will always create a number of 6 digits and it ensures the first digit will never be 0. The code in your question will create a number of less than 6 digits.

Upvotes: 331

Osiris
Osiris

Reputation: 129

npm install --save randomatic

var randomize = require('randomatic');
randomize(pattern, length, options);

Example:

To generate a 10-character randomized string using all available characters:

randomize('*', 10);
//=> 'x2_^-5_T[$'

randomize('Aa0!', 10);
//=> 'LV3u~BSGhw'

a: Lowercase alpha characters (abcdefghijklmnopqrstuvwxyz'

A: Uppercase alpha characters (ABCDEFGHIJKLMNOPQRSTUVWXYZ')

0: Numeric characters (0123456789')

!: Special characters (~!@#$%^&()_+-={}[];\',.)

*: All characters (all of the above combined)

?: Custom characters (pass a string of custom characters to the options)

NPM repo

Upvotes: 1

Demven Weir
Demven Weir

Reputation: 894

Here is my function I use. n - string length you want to generate

function generateRandomNumber(n) {
  return Math.floor(Math.random() * (9 * Math.pow(10, n - 1))) + Math.pow(10, n - 1);
}

Upvotes: 3

Manoj Reddy Mettu
Manoj Reddy Mettu

Reputation: 139

For the length of 6, recursiveness doesn't matter a lot.

function random(len) {
  let result = Math.floor(Math.random() * Math.pow(10, len));

  return (result.toString().length < len) ? random(len) : result;
}

console.log(random(6));

Upvotes: -1

Prashant Dubey
Prashant Dubey

Reputation: 1

  var number = Math.floor(Math.random() * 9000000000) + 1000000000;
    console.log(number);

This can be simplest way and reliable one.

Upvotes: -1

Rafi Henig
Rafi Henig

Reputation: 6424

This code provides nearly full randomness:

function generator() {
    const ran = () => [1, 2, 3, 4, 5, 6, 7, 8, 9, 0].sort((x, z) => {
        ren = Math.random();
        if (ren == 0.5) return 0;
        return ren > 0.5 ? 1 : -1
    })
    return Array(6).fill(null).map(x => ran()[(Math.random() * 9).toFixed()]).join('')
}

console.log(generator())

This code provides complete randomness:

function generator() {

    const ran1 = () => [1, 2, 3, 4, 5, 6, 7, 8, 9, 0].sort((x, z) => {
        ren = Math.random();
        if (ren == 0.5) return 0;
        return ren > 0.5 ? 1 : -1
    })
    const ran2 = () => ran1().sort((x, z) => {
        ren = Math.random();
        if (ren == 0.5) return 0;
        return ren > 0.5 ? 1 : -1
    })

    return Array(6).fill(null).map(x => ran2()[(Math.random() * 9).toFixed()]).join('')
}

console.log(generator())

Upvotes: -2

Olaawo Oluwapelumi
Olaawo Oluwapelumi

Reputation: 51

This is another random number generator that i use often, it also prevent the first digit from been zero(0)

  function randomNumber(length) {
    var text = "";
    var possible = "123456789";
    for (var i = 0; i < length; i++) {
      var sup = Math.floor(Math.random() * possible.length);
      text += i > 0 && sup == i ? "0" : possible.charAt(sup);
    }
    return Number(text);
  }

Upvotes: 3

Sudhanshu Gaur
Sudhanshu Gaur

Reputation: 7664

You can use this module https://www.npmjs.com/package/uid, it generates variable length unique id

uid(10) => "hbswt489ts"
 uid() => "rhvtfnt" Defaults to 7

Or you can have a look at this module https://www.npmjs.com/package/shortid

const shortid = require('shortid');

console.log(shortid.generate());
// PPBqWA9

Hope it works for you :)

Upvotes: 0

Suneel
Suneel

Reputation: 37

"To Generate Random Number Using JS"

console.log(
Math.floor(Math.random() * 1000000)
);
<!DOCTYPE html>
<html>
<body>

<h2>JavaScript Math.random()</h2>

<p id="demo"></p>

</body>
</html>

Upvotes: -1

AnkurJat
AnkurJat

Reputation: 414

I was thinking about the same today and then go with the solution.

var generateOTP = function(otpLength=6) {
  let baseNumber = Math.pow(10, otpLength -1 );
  let number = Math.floor(Math.random()*baseNumber);
  /*
  Check if number have 0 as first digit
  */
  if (number < baseNumber) {
    number += baseNumber;
  }
  return number;
};

Let me know if it has any bug. Thanks.

Upvotes: 0

Manu
Manu

Reputation: 10934

I created the below function to generate random number of fix length:

function getRandomNum(length) {
    var randomNum = 
        (Math.pow(10,length).toString().slice(length-1) + 
        Math.floor((Math.random()*Math.pow(10,length))+1).toString()).slice(-length);
    return randomNum;
}

This will basically add 0's at the beginning to make the length of the number as required.

Upvotes: 1

KhalilRavanna
KhalilRavanna

Reputation: 6058

More generally, generating a random integer with fixed length can be done using Math.pow:

var randomFixedInteger = function (length) {
    return Math.floor(Math.pow(10, length-1) + Math.random() * (Math.pow(10, length) - Math.pow(10, length-1) - 1));
}

To answer the question: randomFixedInteger(6);

Upvotes: 22

sharoz
sharoz

Reputation: 6345

100000 + Math.floor(Math.random() * 900000);

will give a number from 100000 to 999999 (inclusive).

Upvotes: 6

Maksim Gladkov
Maksim Gladkov

Reputation: 3079

I would go with this solution:

Math.floor(Math.random() * 899999 + 100000)

Upvotes: 23

Related Questions