Math.random()和.replace()跨浏览器

时间:2016-06-29 08:41:25

标签: javascript random cross-browser

我最近写了代码,随机生成10个字符。 Math.random()给小数点toString(36),所有数字都将被替换。

Math.random().toString(36).replace(/[^a-z]+/g,'').substr(1,10);

是否有人暗示为什么Firefox(47.0)和Chrome(51)不能同时处理这个问题?

Chrome测试:

Math.random().toString(36).replace(/[^a-z]+/g,'').substr(1,10);
"spkcirhyzb"
"gcqbrmulxe"
"sallvbzqbk"
"pcdcufhqet"
"knfffqsytm"

Firefox测试:

Math.random().toString(36).replace(/[^a-z]+/g,'').substr(1,10);
"zxntpvn"
"hebfyxlt"
"zclj"
"ormtqw"
"cfbsnye"

直播版:



for (var n = 0; n < 5; ++n) {
  console.log(Math.random().toString(36).replace(/[^a-z]+/g,'').substr(1,10));
}
&#13;
&#13;
&#13;

更新(字符串平均值):

&#13;
&#13;
var test;
  var count = 0;
  for (var n = 0; n < 1000; ++n) {
      test = Math.random().toString(36).replace(/[^a-z]+/g,'').substr(1,10);
      count += test.length;
  }
  console.log(count);
  console.log(count/1000);
&#13;
&#13;
&#13;

我的结果:

Chrome - 9.999

Firefox - 6.794

2 个答案:

答案 0 :(得分:5)

因为Chrome的Number#toString(36)实现输出的数字比Firefox更多。考虑数字0.9112907907957448

Chrome:  0.wt16lcd3ae3m96qx2a3v7vi
Firefox: 0.wt16lcd3ae

你可以在这里试试:

&#13;
&#13;
console.log((0.9112907907957448).toString(36));
&#13;
&#13;
&#13;

spec says算法可以依赖于实现,它只需要是一个&#34;泛化&#34; ToString Applied To Number Type。显然,V8团队(Chrome的JavaScript引擎)和SpiderMonkey团队(Firefox&#39; s)的解释不同。

将IEEE-754双精度二进制浮点数(&#34; double&#34;)转换为字符串的规则很复杂,因为双精度程序通常不会精确地存储我们的值把它们想象成存储。例如,0.1实际上不是0.1(导致着名的0.1 + 0.2 != 0.3问题)。它与<{1}} 真的非常接近,但它不是0.1。因此理论上,0.1应该输出(0.1).toString()(我认为这是正确的值)。但是,一般情况下,为这些值创建字符串的算法适用于以下规则:它们只输出足够的数字,如果您接受该字符串并将其转换回浮点数,则可以获得相同的浮点数双。也就是说,即使0.1000000000000000055511151231257827021181583404541015625不是完全 0.1,它也是您回到原来的双倍值所需的所有数字&#39 ;几乎0.1。显然,Chrome在基数36中0.1的实现输出的数字比这更多,可能符合&#34;注2&#34;在上面的第二个链接上,但我不是专家。

这种技术在任何情况下都存在根本缺陷:你用一串近乎纯粹随机的字母和数字字符串并删除数字,然后期望得到至少十个剩余字符。没有办法确定它实际上是真的,甚至不是Chrome。

答案 1 :(得分:1)

这是关于生成10个字符的随机字符串的初始问题的有效解决方案。

正如T. J Crowder指出的那样,您的解决方案无法在任何浏览器中运行,因为您希望它能够正常运行。

&#13;
&#13;
var chars = "abcdefghijklmnopqrstuvwxyz";
var str = '';
for (var i = 0; i < 10; i++) {
    str += chars[Math.floor(Math.random() * chars.length)];
}
                       
console.log(str);
&#13;
&#13;
&#13;