如何使用JavaScript生成固定长度的随机数?


77

我正在尝试生成一个随机数,该随机数必须具有精确的6位数字的固定长度。

我不知道下面给出的JavaScript是否会创建少于6位的数字?

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

我在这里在StackOverflow上找到了这个问题和答案。但是,还不清楚。

编辑:我多次运行上述代码,是的,它经常创建小于6位数字的数字。有没有一种快速/快速的方法来确保它始终是精确的6位数字?



大家好,我要70位数字
Swapnil Yeole,

Answers:


162

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

将始终创建6位数字,并确保第一位永远不会为0。问题中的代码创建少于6位的数字。


14
嘿,您添加了很好的评价。我从不希望第一个数字为0。
hypermiler 2014年

1
@momomo如何寿
Cilan

2
您必须从0-9生成n次随机数。看到我发布的答案
毫米

@Doorhandle要回答有关如何的问题,请添加100000,其后的数字表示仅可以输入高于该数字的数字。获得真实的固定n长度而不损失的唯一可能方法是一次生成一个数字,即n次。还可以得出结论,所有高于10 ^ n的数字也不可能。因此,例如,固定长度2的随机数将为10-99。对于3,100-999。对于4,1000-9999。对于5 10000-99999,依此类推。可以看出,这意味着损失了10%的头皮。对于很大的数字(18、24、48),10%仍然是很多数字。
mmm

1
@momomo他说,具体来说,它需要为6位数字,且第一个数字不为0(请参见上面的注释)
Cilan

28

只有完全可靠的答案才能提供完全的随机性,而不会造成损失。在此答案之前的所有其他字符都会根据您需要的字符数而松散。您想要的越多,他们失去的随机性就越多。

他们通过限制固定长度之前可能的数量来实现这一目标。

因此,例如,固定长度2的随机数将为10-99。对于3,100-999。对于4,1000-9999。对于5 10000-99999,依此类推。从该模式可以看出,这表明随机性损失了10%,因为之前的数字是不可能的。为什么?

对于非常大的数字(18、24、48),仍有10%的数字可供选择。

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

生成器允许无限长的长度而不会造成精度损失,并且具有最低的性能成本。

例:

generate(2)
"03"
generate(2)
"72"
generate(2)
"20"
generate(3)
"301"
generate(3)
"436"
generate(3)
"015"

如您所见,最初甚至包括零,这是额外的 10%损失,除了不可能存在10 ^ n之前的数字。

现在总共占20%。

另外,其他选项对实际生成的字符数有上限。

费用示例:

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

日志:

Time: 0 ms for 7884381040581542028523049580942716270617684062141718855897876833390671831652069714762698108211737288889182869856548142946579393971303478191296939612816492205372814129483213770914444439430297923875275475120712223308258993696422444618241506074080831777597175223850085606310877065533844577763231043780302367695330451000357920496047212646138908106805663879875404784849990477942580056343258756712280958474020627842245866908290819748829427029211991533809630060693336825924167793796369987750553539230834216505824880709596544701685608502486365633618424746636614437646240783649056696052311741095247677377387232206206230001648953246132624571185908487227730250573902216708727944082363775298758556612347564746106354407311558683595834088577220946790036272364740219788470832285646664462382109714500242379237782088931632873392735450875490295512846026376692233811845787949465417190308589695423418373731970944293954443996348633968914665773009376928939207861596826457540403314327582156399232931348229798533882278769760

更加铁杆:

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

“必须具有精确的6位数字的固定长度” ...“我永远不希望第一位数字为0。要点。– hypermiler”。我很佩服您的技术并不断前进,我敢肯定,这个答案可能对其他人有用,但我只是在说。不利的一面是,您的算法是大规模递归的,因此我不认为它“允许以最小的性能代价实现无限长的长度”。
randomsock

@randomsock仅在您需要的数字多于12时才是递归的,在这种情况下,它将一次生成12个数字。最低的性能成本,是的。这样做的目的是用于随机数字符串,其中随机性很重要,或者内容是什么样。开始时零值对我们来说还可以。有效的随机字符串为0000000123,但此处不会通过其他任何方法生成此字符串。
mmm


13

更一般而言,可以使用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));
}

要回答这个问题: randomFixedInteger(6);


最佳和最通用的答案。
Ansjovis86

我认为这不会产生一些0-first-padding数字,例如00382。因此,对于所有范围而言,它都不是完全随机的。
kakadais '18 -10-10

4

根据您提供的链接,正确答案应为

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

Math.random()返回的浮点数介于0和1之间,因此最小数字为100000,最大为999999。正好是您所需要的6位:)



2

这是我使用的功能。n-您要生成的字符串长度

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


1

这是我经常使用的另一个随机数生成器,它还可以防止第一个数字为零(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);
  }


1
npm install --save randomatic

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

例:

要使用所有可用字符生成10个字符的随机字符串:

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

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

a:小写字母字符(abcdefghijklmnopqrstuvwxyz'

A:大写字母字符(ABCDEFGHIJKLMNOPQRSTUVWXYZ')

0:数字字符(0123456789')

!:特殊字符(〜!@#$%^&()_ +-= {} []; \',.)

*:所有字符(以上所有字符的总和)

?:自定义字符(将一串自定义字符传递给选项)

NPM回购


0

我创建了以下函数来生成固定长度的随机数:

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

这基本上会在开头添加0,以根据需要增加数字的长度。


0

我今天也在考虑相同的问题,然后再提出解决方案。

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

让我知道它是否有任何错误。谢谢。


这确实有一个错误:您生成100000到199999之间的数字的可能性是其他任何数字的两倍。
G. Sliepen '18

0

“使用JS生成随机数”

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

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

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

</body>
</html>


0

这段代码提供了几乎完全的随机性:

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

这段代码提供了完全的随机性:

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


0

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

这可能是最简单且可靠的方法。


0

对于6的长度,递归无关紧要。

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


0

如果您还希望第一个数字能够为0,这是我的解决方案:

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



0

生成一个随机数,该随机数必须具有精确的6位数字的固定长度:

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

2
希望它将解决问题,但请在其中添加代码说明,以便用户完全理解他/她真正想要的。
贾米尔·帕特尔

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

如果需要整数,请在结果上使用parseInt()Number()。如果您不希望第一个整数为0,则可以使用padEnd()代替padStart()


0

您可以使用以下代码生成一个始终为6位数字的随机数:

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

希望这对每个人都有用:)

简而言之,它是如何Math.random()产生一个0到1之间的随机数,我们将其转换为字符串并使用,.toString()并使用.substr()带有参数的参数从该字符串中获取6位数字的样本2, 6从第二个字符开始该样本并继续进行6个字符。

可以用于任何长度的数字。

如果您想对此进行更多阅读,这里有一些指向文档的链接,以节省您的搜索时间:

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

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

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


-2

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

更新:此方法有几个缺陷:-有时,如果数字的左边用零填充,则位数可能会减少。


2
这是错误的,原因有几个。无法保证您从字符串中选取的片段不以零开头。另外,如果有一种很好的方法来解决普通数学函数的问题,请避免在字符串之间来回转换数字。
G. Sliepen '18

@ G.Sliepen感谢您纠正我。就我的学习而言,您还可以详细说明为什么数字不应该来自字符串吗?任何已知的缺陷?谢谢
库沙格拉·古尔

1
在字符串之间来回转换很慢,并且很容易忘记极端情况,例如:如果一个数字为负数,零,是一个浮点数,被转换为指数表示法,等等。例如,Math.random()可能恰好返回0或1,然后将它们转换为字符串'0''1',然后.slice(2, ...)返回空字符串,然后parseInt()返回NaN
G. Sliepen

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.