【问题标题】:How to Generate a random number of fixed length using JavaScript?如何使用 JavaScript 生成一个固定长度的随机数?
【发布时间】:2014-03-16 00:17:22
【问题描述】:

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

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

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

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

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

【问题讨论】:

标签: javascript random numbers


【解决方案1】:

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

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

【讨论】:

  • 嘿,你添加了一个很好的评论。我从不希望第一个数字是 0。好点。
  • @momomo 怎么样
  • 你必须生成一个 0-9 的随机数,n 次。查看我发布的答案
  • @momomo 他特别说它需要 6 位数字,第一个数字没有 0(见上面的评论)
  • 那么,如果随机数是 900000,那么您将遇到麻烦(并且您要添加 100000,使其等于 1000000,即 7 位数)。我更喜欢 Maksim Gladkov 下面的答案,以便从 899999 而不是 900000 中获取随机数。
【解决方案2】:

只有完全可靠的答案才能提供完全随机性,而不会丢失。此答案之前的其他人都会根据您想要的字符数而丢失。你想要的越多,他们就越失去随机性。

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

例如,固定长度 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 只有在您需要的数字超过 12 个时才会递归,在这种情况下,它将一次生成 12 个数字。最低性能成本,是的。这样做的目的是用于随机数字符串,其中随机性很重要,或者内容看起来像与否。零开始对我们来说没问题。一个有效的随机字符串是 0000000123,但是除了这个之外,这里的任何其他方法都不会生成它。
【解决方案3】:

我会选择这个解决方案:

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

【讨论】:

  • 好的。我知道了。是的。这样就可以了!
【解决方案4】:

更一般地说,生成一个固定长度的随机整数可以使用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);

【讨论】:

  • 最佳和最通用的答案。
  • 我认为这不会产生一些 0-first-padding 数字,例如 00382。所以对于所有范围来说,这不会是完全随机的。
【解决方案5】:

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

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

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

简单地说这是如何工作的Math.random() 生成一个介于 0 和 1 之间的随机数,我们将其转换为字符串并使用 .toString() 并使用 .substr() 从所述字符串中获取 6 位样本,参数为 2, 6 到从第 2 个字符开始示例并继续 6 个字符。

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

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

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

【讨论】:

  • 如果 Math.random() 返回 0.5 你将得到 1 位数的结果
【解决方案6】:
100000 + Math.floor(Math.random() * 900000);

将给出一个从 100000 到 999999(含)的数字。

【讨论】:

  • 不!它可能看起来像一个极端情况,但如果 Math.random() 返回 1,此解决方案可能会产生 1000000,这是一个 7 位数字。
  • @SaeedAhadian 检查文档。 “在 0 到小于 1 的范围内”developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
  • 好点!我不知道它不包括 1。谢谢。
【解决方案7】:

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

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

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

【讨论】:

    【解决方案8】:

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

    【讨论】:

      【解决方案9】:

      这是我使用的函数。 n - 要生成的字符串长度

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

      【讨论】:

        【解决方案10】:

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

        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,以使数字的长度符合要求。

        【讨论】:

          【解决方案11】:
          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 repo

          【讨论】:

            【解决方案12】:

            我使用randojs 使随机性更简单、更易读。您可以使用 randojs 像这样在 100000 和 999999 之间选择一个随机整数:

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

            【讨论】:

              【解决方案13】:
              let length = 6;
              ("0".repeat(length) + Math.floor(Math.random() * 10 ** length)).slice(-length);
              

              Math.random() - 返回 0 - 1 之间的浮点数

              10 ** length - 将它乘以长度,这样我们就可以得到 1 - 6 个带小数的长度数字

              Math.floor() - 将上述数字返回为整数(给定数字的最大整数)。

              如果我们得到少于 6 位的数字怎么办?

              这就是为什么你必须附加0s 的原因。 "0".repeat() 重复给定的字符串 0

              所以我们可能会得到超过 6 个数字,对吧? 这就是我们必须使用"".slice() 方法的原因。它返回给定索引内的数组。通过给出负值,它从最后一个元素开始计数。

              【讨论】:

                【解决方案14】:

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

                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 之间的数字的可能性是任何其他数字的两倍。
                【解决方案15】:

                “使用JS生成随机数”

                console.log(
                Math.floor(Math.random() * 1000000)
                );
                <!DOCTYPE html>
                <html>
                <body>
                
                <h2>JavaScript Math.random()</h2>
                
                <p id="demo"></p>
                
                </body>
                </html>

                【讨论】:

                  【解决方案16】:

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

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

                  【讨论】:

                    【解决方案17】:

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

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

                    【讨论】:

                      【解决方案18】:

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

                      【讨论】:

                        【解决方案19】:

                        如果您还希望第一个数字能够为 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())

                        【讨论】:

                          【解决方案20】:

                          生成一个固定长度必须正好为 6 位的随机数:

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

                          【讨论】:

                          • 希望它能解决问题,但请添加对代码的解释,以便用户完全理解他/她真正想要的。
                          【解决方案21】:
                          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()。

                          【讨论】:

                            【解决方案22】:

                            生成一个 6 位数的随机数:

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

                            结果 = 500229

                            生成一个 4 位数的随机数:

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

                            结果 = 8751

                            【讨论】:

                            • 如果 Math.random() 返回 0.00001 则结果将只有 1 位
                            【解决方案23】:

                            任意精度的short

                            下面的代码总是生成带有n 数字的字符串-sn-p 中的解决方案使用它

                            "x".repeat(n).replace(/x/g,x=>Math.random()*10|0)
                            

                            let gen = n=> "x".repeat(n).replace(/x/g,x=>Math.random()*10|0)
                            
                            // 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

                            【讨论】:

                              【解决方案24】:

                              你可以使用这个模块https://www.npmjs.com/package/uid,它会生成可变长度的唯一id

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

                              或者你可以看看这个模块https://www.npmjs.com/package/shortid

                              const shortid = require('shortid');
                              
                              console.log(shortid.generate());
                              // PPBqWA9
                              

                              希望它对你有用:)

                              【讨论】:

                              • @OlegMikhailov 现在解释了吗,还是没有提供信息?
                              【解决方案25】:

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

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

                              【讨论】:

                              • 这是错误的,有几个原因。不能保证您从字符串中选择的切片不以零开头。此外,如果有一种非常好的方法可以解决普通数学函数的问题,请避免将数字与字符串相互转换。
                              • @G.Sliepen 感谢您纠正我。为了我的学习,您能否再详细说明一下为什么数字不应该从字符串到字符串?任何已知的缺陷?谢谢
                              • 字符串之间的转换很慢,而且很容易忘记极端情况,例如:如果一个数字是负数,零,是一个浮点数,正在转换为指数符号怎么办, 等等。例如,Math.random() 可能准确返回 0 或 1,这些将转换为字符串 '0' 或 '1',然后 .slice(2, ...) 将返回一个空字符串,然后 parseInt() 将返回 NaN .
                              猜你喜欢
                              • 2019-06-23
                              • 1970-01-01
                              • 2020-03-11
                              • 1970-01-01
                              • 2021-03-15
                              • 2016-06-17
                              • 1970-01-01
                              • 1970-01-01
                              • 2018-06-19
                              相关资源
                              最近更新 更多