155

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?

1

28 Answers 28

331

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.

Sign up to request clarification or add additional context in comments.

9 Comments

Hey, you added a good commment. I never want the first digit to be 0. Good point.
you have to generate a random number from 0-9, n times. see posted answer by me
@momomo he says specifically it needs to be 6 digits without 0 as the first number (see above comment)
Well you will be in trouble if the random number is 900000 (and you are adding 100000, making it equal to 1000000, which will be 7 digits). I would prefer the answer below by Maksim Gladkov to get the random number from 899999 instead of 900000).
Math.random is 0 - 0.9999999999999999 so.. it wont hit 7 digits. console.log(Math.floor(100000 + 0 * 900000)); = 100000 console.log(Math.floor(100000 + 0.9999999999999999 * 900000)); = 999999
|
43

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

3 Comments

"must have a fixed length of exactly 6 digits" ... "I never want the first digit to be 0. Good point. – hypermiler". I admire your engineering and pushing the envelope, and I'm sure this answer might be useful to someone else, but just saying. On the downside, your algorithm is massively recursive so I'm not convinced it "allows for ~infinite length [...] with minimal performance cost".
@randomsock it is only recursive if you need more numbers than 12, in which case it will generate 12 numbers at a time. minimal performance cost, yes. The purpose of this is the use for random number strings, where randomness matters, or what the content looks like or not. zeros at start was ok for us. a valid random string is 0000000123 but this won't be generated in any of the other methods here, other than this one.
This function sometimes generates numbers of length less than the specified length. i-e generate(6), also generates numbers of length 5. to fix: replace the last line with: return ("" + number).substring(0, length);
23

I would go with this solution:

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

2 Comments

OK. I get it. YES. That will do it!
Actually you can put 900000 instead of 899999 because Math.rand() will return a number in range [0,1[ that means 0 inclusive and 1 exclusive so it will never be equals to 1 as explained here
23

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);

2 Comments

Best and most versatile answer.
I think this wouldn't make some 0-first-padding number, something like 00382. So that wouldn't be exact random for all range.
22

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

4 Comments

if Math.random() returns 0.5 you will get 1 digit result
This can work then Math.random().toString().substr(2, 6).repeat(6).substr(2, 6); @KamilKiełczewski
It is better to padStart to desired length.
substr method deprecated instead usign .slice(2,8)
9

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

3 Comments

This is illegally beautifully written
Can you explain to me why 10|0 is necessary here?
8

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 :)

Comments

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

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

3 Comments

No! It might look like a corner case but if Math.random() returns 1, this solution might yield 1000000 which is a 7-digit number.
@SaeedAhadian Check the docs. "in the range 0 to less than 1" developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Good point! I didn't know it's not inclusive of 1. Thanks for that.
3

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);
  }

Comments

3

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);
}

Comments

2
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.

Comments

1

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.

Comments

1
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

Comments

1

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>

Comments

1
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().

Comments

0

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.

1 Comment

This has indeed a bug: you make it twice as likely to generate a number between 100000 and 199999 than any other number.
0

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 :)

Comments

0

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())

Comments

0

my i came across this problem today .. and for the love of all things great and small thought i would include a solution, that ( ahem ) doesnt involve downloading libraries or cryptic mathematics that you have to sit down with a pencil and work out what is actually going on

so first some background, me whilst chucking together a small program, that would of course never be used again, decided that an easy way to generate an id would be with the following code, until i came to need to validate that id

turns out Math.random() is producing numbers of differing length, any search will tell you 'yep, between 15-17 digits' until today 18 digits popped up

    //gen-id

            var id                = gen();
            output.textContent    = id;
            
            function gen(){
            
                  var n     = Math.random();
                  var s     = (n+'').slice(2);
                  s         = s.padStart(20,'0');   //17,18,19, ...
                  var id    = 'x'+s;
                  return id;
                  
            }//gen
<style>#output{font-family:monospace;white-space:pre}</style>
<div id=output></div>

ok enough, just generate a number of fixed length then

//gen-num

        function rnd(n){
          
              var str     = '';
              var c       = '0123456789';
              var index   = ()=>Math.floor(Math.random()*10);
              
              for(var j=0;j<n;j++){
                
                    var i   = index();
                    str    += c[i];
                    
              }//for
              
              return str;
          
        }//rnd
        
        rnd.nonzero   = function(n){
          
              var str   = '0';
              
              while(str[0]=='0'){
                
                    str   = rnd(n);
                    
              }//while
              
              return str;
              
        }//non
        
        var log   = v=>output.textContent+=v+'\n';
        
        log(rnd(6));
        log(rnd.nonzero(6));
<style>#output{font-family:monospace;white-space:pre}</style>
<div id=output></div>

Comments

0

Here is function (randomNrWithFixedLength) to create a random number with length [len] using a random number creator factory (randomNumberRangeFactory) which uses crypto.getRandomValues to create random numbers.

See also

const len = 6;
const {getRandomNr} = randomNumberRangeFactory();

console.log(`length: ${len}, so\nminimum value: ${
  (10**(len-1)).toLocaleString()}\nmaximum value: ${
  (10**len-1).toLocaleString()}`);

// create 5 random numbers with length (len) 6
for (let i = 0; i < 5; i += 1) {
  console.log(randomNrWithFixedLength(len).toLocaleString());
}

function randomNrWithFixedLength(len) {
  len = len < 2 ? 2 : len;
  const [min, max] = [10**(len-1)-1, 10**len];
  return getRandomNr({min, max});
  //                  ^ [inclusive] is not
  // provided, so min (99999) and max (1000000)
  // can never be be the result
}

function randomNumberRangeFactory() {
  return {
    getRandomNrRange: getRange,
    getRandomNr(spec) { return getRange({...spec, len: 1})[0]; },
    getUniqueRandomNrRange: getUniqueValues,
  };

  /*
    When [len] exceeds 16384 the ArrayBufferView's byte length 
    will exceed the available bytes of entropy 
    (65536 in the crypto API, Uint32Array is 4 bytes/element).
    So for n > 16384 we concatenate chunks of 16384 random numbers.

    Note: if for the resolved values of [min] and [max] min exceeds max,
    the values are swapped.
  */
  function getRange(spec) {
    const chunkSize = 2**14;
    const [min, max, len] = validateInput(spec);

    switch(true) {
      case len <= chunkSize: 
        return createArrayOfRandomValues(len, min, max);
      default: 
        let iterations = Math.floor(len / chunkSize);
        const remainder = len % chunkSize;
        const res = [];

        while (iterations--) { 
          res.push(...createArrayOfRandomValues(chunkSize, min, max)); 
        }

        remainder > 0 && 
          res.push(...createArrayOfRandomValues(remainder, min, max));

        return res;
    }
  }

  function getUniqueValues(spec) {
    const shouldBeLen = spec.len?.constructor === Number && 
     spec.len > 0 ? spec.len : 1;
    let values;

    switch(true) {
      case shouldBeLen === 1: return getRange({...spec, len: shouldBeLen});
      default: 
        values = new Set([...getRange(spec)]);
        let diff = shouldBeLen - [...values].length;
        return diff > 0 ? redo(diff) : [...values];
    }
   
    function redo(diff) {
      const additional = getRange({...spec, len: diff});
      additional.forEach(v => values.add(v));
      diff = shouldBeLen - [...values].length;
      return  diff > 0 ? redo(diff) : [...values];
    }
  }

  function checkInclusive(inclusive) {
    const kvArray = inclusive?.constructor === Object &&
     Object.entries(inclusive).filter(([k,v]) => /^(min|max)$/.test(k) && 
      v?.constructor === Boolean) || 
     [];

    switch(kvArray.length) {
      case 0: return { min: false, max: false };
      case 1: kvArray.push([kvArray[0][0] === `min` ? `max` : `min`, false]);
      default: return Object.fromEntries(kvArray);
    }
  }

  function validateInput(spec) {
    let {min, max, len, inclusive} = spec || {};
    inclusive = checkInclusive(inclusive);
    min = min?.constructor === Number ? min : 1;
    max = max?.constructor === Number ? max : Number.MAX_SAFE_INTEGER - 1;
    len = len?.constructor === Number && len > 0 ? len : 1;
    min -= +!!inclusive.min;
    max += +!!inclusive.max;
    [min, max] = min > max ? [max, min] : [min, max];
    return [min, max, len];
  }

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

Comments

-1

"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>

Comments

-1

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

This can be simplest way and reliable one.

Comments

-1

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));

Comments

-1

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

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

1 Comment

Hope It will solve issue but please add explanation of your code with it so user will get perfect understanding which he/she really wants.
-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

1 Comment

if Math.random() returns 0.00001 the result will have only 1 digit
-2

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())

Comments

-3

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'));

2 Comments

Hi. You can add the value 0 to your characters if type === number: characters = '0123456789'; Also, not strictly necessary, but semicolons at the end of every sentence might be a good team convention
As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.
-4
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.

3 Comments

This is wrong for several reasons. There is no guarantee that the slice you pick from the string does not start with zeroes. Also, avoid converting numbers to and from strings if there is a perfectly fine way to solve the issue with normal math functions.
@G.Sliepen Thanks for correcting me. For my learning, could you also elaborate a little more on why numbers should not be from and to string? Any known flaws? Thanks
Converting to and from strings is slow, and it is easy to forget about corner cases, for example: what if a number is negative, zero, is a floating point number, is being converted to exponential notation, and so on. For example, Math.random() might return 0 or 1 exactly, and these would be converted to the strings '0' or '1', and then .slice(2, ...) would return an empty string, and then parseInt() would return NaN.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.