Forelight
Forelight

Reputation: 305

Java riddle: need a stable random that persistes in a JVM but is different in another JVM

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

Answers (3)

Tilo
Tilo

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

emory
emory

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

Andy Thomas
Andy Thomas

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

Related Questions