Reputation: 305
I need to find a way to obtain from the JVM a (somewhat) random string or number that I don't have to store. But I will need it multiple times over the life of a JVM, so subsequent calls to this method must return the same value. Further, after the JVM is restarted, the same code must yield a different, but still stable value. The quality of randomness is not important, so long as it's sufficiently hard to guess.
Upvotes: 0
Views: 442
Reputation: 3325
Look into the methods of RuntimeMXBean. For example you could do:
RuntimeMXBean rmxb = ManagementFactory.getRuntimeMXBean();
String jvmId = rmxb.getVmName() + "-" + rmxb.getStartTime();
// use jvmId.intern().hashCode() as seed for a RNG
As emroy pointed out, it is possible that two JVMs get started at the same time. I suggest concatenating the machine's MAC address to the jvmId
if this a concern:
InetAddress localHost = InetAddress.getLocalHost();
NetworkInterface networkInterface = NetworkInterface.getByInetAddress(localHost);
byte[] macAddress = networkInterface.getHardwareAddress();
jvmId += "-" + Arrays.toString(macAddress);
Upvotes: 1
Reputation: 10891
I would suggest using the hashCode of a lazily initiated static object. The below code does not seem to work. I would guess SAXParserFactory is not in fact lazily initiated.
class One
{
public static void main ( String [ ] args )
{
while(Math.random()<0.99){
new Object();
}
System.out.println(javax.xml.parsers.SAXParserFactory.newInstance().hashCode());
}
}
Upvotes: 0
Reputation: 86429
Just seed the Random differently in the different VMs.
public class MyClass {
private int myStableRandomValue = new Random( System.currentTimeMillis() ).nextInt();
...
}
EDIT:
If you really don't want to store the value, you could seed the Random method above with the process ID, and call it every time the value is requested -- if potential attackers do not have access to the process ID.
private int getMyStableRandomValue() {
return new Random( getProcessID() ).nextInt();
}
Upvotes: 5