预测Javascript的Math.random的种子 [英] Predict the Seed of Javascript's Math.random

查看:304
本文介绍了预测Javascript的Math.random的种子的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好的,我正在研究如何使用Math.random方法生成随机数。到目前为止,我学会了它从一个随机种子开始,并将该种子插入到一些复杂的方程中以创建一个随机数。如果种子总是一样,结果总是一样吗?

Okay, so I'm doing some research on how random numbers are generated with the Math.random method. So far I learned that it starts with a "random" seed, and that seed is plugged into some complex equation to create a random number. If the seed is always the same, will the outcome always be the same?

我听说Math.random的种子是通过当前时间生成的,是正确的?他们必须使用当前时间一直到mili-seconds或其他东西,因为如果你没有,你会得到相同的结果。

I heard that the seeds for Math.random are generated through the current time, is that correct? They must use the current time all the way down to the mili-seconds or something, because if you didn't you would get the same outcome.

究竟是什么种子?是时间如10:45还是时间和日期,如10:45 11/8/12或某种组合?

What exactly is the seed? Is it the time such as "10:45" or the time AND date such as "10:45 11/8/12" or some combination?

我怎么能找到种子,所以我可以预测输出?

How can I find the seed, so I can predict the output?

我希望能够插入这个:

alert(Math.floor((Math.random()*10)+1));

进入我的网址栏,并能够预测结果。这可能吗?

into my url bar, and be able to predict the result. Is that possible?

推荐答案

我查看了Rhino 源代码,找出他们使用的伪随机函数。显然他们回退到 Math.random 函数/api/java/lang/Math.html#random()rel =noreferrertitle =Math(Java 2 Platform SE v1.4.2)> Java标准库

I looked through the Rhino source code to find out which pseudo-random function they use. Apparently they fall back to the Math.random function defined in the Java standard library.

Math.random 的文档说:


返回带有正号的double值,大于或等于0.0且小于1.0。返回值是伪随机选择的,具有来自该范围的(近似)均匀分布。

Returns a double value with a positive sign, greater than or equal to 0.0 and less than 1.0. Returned values are chosen pseudorandomly with (approximately) uniform distribution from that range.

首次调用此方法时,它会创建一个新的伪随机数生成器,就像通过表达式

When this method is first called, it creates a single new pseudorandom-number generator, exactly as if by the expression



new java.util.Random




此新的伪随机数生成器此后用于对此方法的所有调用,并且在其他地方使用。

This new pseudorandom-number generator is used thereafter for all calls to this method and is used nowhere else.

此方法已正确同步,以允许多个线程正确使用。但是,如果许多线程需要以很高的速率生成伪随机数,它可能会减少每个线程争用自己的伪随机数生成器。

This method is properly synchronized to allow correct use by more than one thread. However, if many threads need to generate pseudorandom numbers at a great rate, it may reduce contention for each thread to have its own pseudorandom-number generator.

所以我检查了 java.util.Random 的文档,发现这个(对于默认构造函数):

So I checked the documentation for java.util.Random and found this (for the default constructor):


创建一个新的随机数生成器。它的种子初始化为基于当前时间的值:

Creates a new random number generator. Its seed is initialized to a value based on the current time:



public Random() { this(System.currentTimeMillis()); }




在同一毫秒内创建的两个随机对象将具有相同的序列随机数。

Two Random objects created within the same millisecond will have the same sequence of random numbers.

所以现在我们确定种子是当前时间(以毫秒为单位)。此外,第二个构造函数说:

So now we know for sure that the seed is the current time in milliseconds. Also, the documentation for the second constructor says:


创建一个新的随机数生成器使用单个长种子:

Creates a new random number generator using a single long seed:



public Random(long seed) { setSeed(seed); }




由旁边的方法用来保存伪随机数生成器的状态。

Used by method next to hold the state of the pseudorandom number generator.

setSeed 文档 c $ c>方法说:

The documentation for the setSeed method says:


使用单个长种子设置此随机数生成器的种子。 setSeed的一般契约是它改变了这个随机数生成器对象的状态,以便与刚刚用参数种子作为种子创建的状态完全相同。方法setSeed由Random类实现,如下所示:

Sets the seed of this random number generator using a single long seed. The general contract of setSeed is that it alters the state of this random number generator object so as to be in exactly the same state as if it had just been created with the argument seed as a seed. The method setSeed is implemented by class Random as follows:



synchronized public void setSeed(long seed) {
    this.seed = (seed ^ 0x5DEECE66DL) & ((1L << 48) - 1);
    haveNextNextGaussian = false;
}




按类Random执行setSeed碰巧仅使用给定种子的48位。然而,通常,重写方法可以使用长参数的所有64位作为种子值。注意:尽管种子值是AtomicLong,但仍必须同步此方法以确保hasNextNextGaussian的正确语义。

The implementation of setSeed by class Random happens to use only 48 bits of the given seed. In general, however, an overriding method may use all 64 bits of the long argument as a seed value. Note: Although the seed value is an AtomicLong, this method must still be synchronized to ensure correct semantics of haveNextNextGaussian.

实际方法 nextDouble


从这个随机数生成器的序列中返回下一个伪随机数,均匀分布在0.0和1.0之间的double值。

Returns the next pseudorandom, uniformly distributed double value between 0.0 and 1.0 from this random number generator's sequence.

执行 nextDouble 函数如下:

public double nextDouble() {
    return (((long)next(26) << 27) + next(27))
        / (double)(1L << 53);
}

显然它取决于 next 函数:


生成下一个伪随机数。子类应该覆盖它,因为所有其他方法都使用它。

Generates the next pseudorandom number. Subclass should override this, as this is used by all other methods.

next

The implementation of the next function is as follows:

synchronized protected int next(int bits) {
    seed = (seed * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1);
    return (int)(seed >>> (48 - bits));
}

这是你正在寻找的伪随机函数。正如文档所述:

That's the pseudo-random function you are looking for. As it's said in the documentation:


这是一个线性同余伪随机数生成器,由DH Lehmer定义并由Donald E. Knuth描述在计算机程序设计的艺术,第2卷:研究数值算法,第3.2.1节。

This is a linear congruential pseudorandom number generator, as defined by D. H. Lehmer and described by Donald E. Knuth in The Art of Computer Programming, Volume 2: Seminumerical Algorithms, section 3.2.1.

但请注意,这只是随机数Rhino使用的发电机。其他实现如Spidermonkey和V8可能有自己的伪随机数生成器。

Note however that this is only the random number generator used by Rhino. Other implementations like Spidermonkey and V8 may have their own pseudo-random number generators.

这篇关于预测Javascript的Math.random的种子的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆