ChatGPT解决这个技术问题 Extra ChatGPT

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?

Possible duplicate of Random number with fixed length
Hello Guys, I want same with 70 digit length.

S
Sangwin Gawande

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.


Hey, you added a good commment. I never want the first digit to be 0. Good point.
@momomo how tho
you have to generate a random number from 0-9, n times. see posted answer by me
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
m
mjs

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) {
        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.   
        
        if ( n > max ) {
                return generate(max) + generate(n - max);
        }
        
        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;
        
        return ("" + number).substring(add); 
}

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"

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

"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);
M
Maksim Gladkov

I would go with this solution:

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

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
K
KhalilRavanna

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


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.
I
I-EAT-DATA

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


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.
K
Kamil Kiełczewski

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


This is illegally beautifully written
s
sharoz
100000 + Math.floor(Math.random() * 900000);

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


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.
A
Arthur Grishin

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


D
Demven Weir

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


O
Olaawo Oluwapelumi

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


P
Puvipavan
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.


P
Peter

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.


O
Osiris
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


A
Aaron Plocharczyk

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


A
AnkurJat

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.


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

"To Generate Random Number Using JS"

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

JavaScript Math.random()


R
Rafi Henig

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


P
Prashant Dubey

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

This can be simplest way and reliable one.


M
Manoj Reddy Mettu

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


R
Ricki-BumbleDev

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


S
Stephen Yeung

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

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

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.
S
Shantanu Kawale
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().


T
Toni

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


if Math.random() returns 0.00001 the result will have only 1 digit
S
Sudhanshu Gaur

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


@OlegMikhailov Is it explained now, or still not informative?
K
Kushagra Gour

parseInt(Math.random().toString().slice(2,Math.min(length+2, 18)), 10); // 18 -> due to max digits in Math.random

Update: This method has few flaws: - Sometimes the number of digits might be lesser if its left padded with zeroes.


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.