日历类错误并生成数字

时间:2017-02-12 18:02:57

标签: java random time

我尝试使用给定日期生成随机数,以便在Java中创建良好的伪随机数。我决定使用Calendar类并计算当天的毫秒数。这在一定程度上起作用,但是当我启动程序时,我只能获得不同的随机值。在程序中再运行它只会给我相同的数字。我使用Thread.sleep()来确保时间上存在实际差异,但我仍然得到相同的数字。 这是我打电话的方法(来自另一个班级)

public long genRNG()
{
    long mask = 0xFFFF000000000000L;
    long randomValue = seed & mask;
    seed = 0x5D588B656C078965L * cal.get(Calendar.MILLISECOND) + 0x0000000000269EC3;
    return randomValue;
}

这是我的主要方法

public static void main(String[] args) throws InterruptedException
{
    Seed key = new Seed();
    for (int x = 0; x <=10; x++)
    {
        Thread.sleep(200);
        System.out.println(key.genRNG());
    }
}

和给定的输出:

-7389844038561562624
-7389844038561562624
-7389844038561562624
-7389844038561562624
-7389844038561562624
-7389844038561562624
-7389844038561562624
-7389844038561562624
-7389844038561562624

1 个答案:

答案 0 :(得分:1)

您似乎每次都将mask设置为相同的值,并且seed每次设置为相同的值,因此seed & mask每次都会产生相同的值。 Calendar对象在实例化后不会自动更改其值 - 换句话说,它保留了构造它时所花费的时间(通常是构建时的时间),直到您明确地改变它。因此,有一项建议是在每次调用cal时重新初始化genRNG()

我已将cal更改为本地变量:

    long mask = 0xFFFF000000000000L;
    long randomValue = seed & mask;
    Calendar cal = Calendar.getInstance();
    seed = 0x5D588B656C078965L * cal.get(Calendar.MILLISECOND) + 0x0000000000269EC3;
    return randomValue;

现在我可以获得如下输出:

0
8430738502437568512
-2453898846963499008
2916080758722396160
3291568377654411264
-1326873040214032384
-951385421282017280
1212312724692795392
-3406128693175648256
-1298444067566256128
-5916885485434699776

初始0来自seed尚未初始化。我收集它并不是你代码中的问题。

但是,我不认为你在那里。 Calendar.get(Calendar.MILLISECOND)始终返回0到999之间的值,因此您最多可以获得1000个不同的“随机”值。存储在long中并不是很多。例如,你可能会得到更多:

    seed = 0x5D588B656C078965L * System.currentTimeMillis() + 0x0000000000269EC3;

如果由于某种原因你想要一个当前时间的对象而不是long来自System.currentTimeMillis(),如果你可以使用Java 8,我建议{ {1}}。它为您提供了相同的Instant.now().toEpochMilli()值,但long为您提供了一个表示当前时间的对象,与Instant.now()非常相似,如果您想将其用于其他目的,则只会更现代,更通用

另一个问题是因为掩码,你的值总是以二进制表示的48个零结尾(很容易看到所有的值都是偶数)。也许这是设计的?

此外,我认为您不仅仅使用Calendar.getInstance()