0

我需要找到一种方法来从 JVM 获取一个(有点)我不必存储的随机字符串或数字。但是在 JVM 的整个生命周期中我将多次需要它,因此对该方法的后续调用必须返回相同的值。此外,在 JVM 重新启动后,相同的代码必须产生不同但仍然稳定的值。随机性的质量并不重要,只要它足够难以猜测。

4

3 回答 3

5

只需在不同的 VM 中以不同的方式播种 Random 即可。

public class MyClass {
     private int myStableRandomValue = new Random( System.currentTimeMillis() ).nextInt();
     ...
}

编辑

如果您真的不想存储该值,您可以使用进程 ID 为上面的 Random 方法播种,并在每次请求该值时调用它——如果潜在的攻击者无权访问进程 ID。

     private int getMyStableRandomValue() { 
        return new Random( getProcessID() ).nextInt();
     }
于 2013-04-29T22:21:46.113 回答
1

查看RuntimeMXBean的方法。例如你可以这样做:

RuntimeMXBean rmxb = ManagementFactory.getRuntimeMXBean(); 
String jvmId = rmxb.getVmName() + "-" + rmxb.getStartTime();
// use jvmId.intern().hashCode() as seed for a RNG

正如 emroy 指出的,有可能两个 JVM 同时启动。jvmId如果这是一个问题,我建议将机器的 MAC 地址连接到:

InetAddress localHost = InetAddress.getLocalHost();
NetworkInterface networkInterface = NetworkInterface.getByInetAddress(localHost);
byte[] macAddress = networkInterface.getHardwareAddress();
jvmId += "-" + Arrays.toString(macAddress);
于 2013-04-29T22:48:40.177 回答
0

我建议使用延迟启动的静态对象的 hashCode。下面的代码似乎不起作用。我猜 SAXParserFactory 实际上并不是懒惰地启动的。

class One
{
     public static void main ( String [ ] args )
     {
    while(Math.random()<0.99){
        new Object();
    }
    System.out.println(javax.xml.parsers.SAXParserFactory.newInstance().hashCode());
     }
}
于 2013-04-29T22:59:04.457 回答