On 09/16/2013 03:54 PM, Doug Lea wrote:
On 09/16/2013 08:46 AM, Peter Levart wrote:

What worries me is that InetAddress.getLocalHost() involves name
service look-up. It depends on configuration, but on my computer, it takes about 5s to evaluate the hostname -> IP mapping the first time the program is run.

NetworkInterface also has one method called getHardwareAddress(). This might me
interesting too...

Using NetworkInterface.getHardwareAddress() is a good idea; thanks!
Using only one of them should suffice. And just giving up on
SecurityException seems fine.

Could you check that this performs reasonably on your
unusually-configured machine?

I checked and it performs fast. It doesn't involve name service look-up.


 private static long initialSeed() {
        String pp = java.security.AccessController.doPrivileged(
                new sun.security.action.GetPropertyAction(
                        "java.util.secureRandomSeed"));
        if (pp != null && pp.equalsIgnoreCase("true")) {
            byte[] seedBytes = java.security.SecureRandom.getSeed(8);
            long s = (long)(seedBytes[0]) & 0xffL;
            for (int i = 1; i < 8; ++i)
                s = (s << 8) | ((long)(seedBytes[i]) & 0xffL);
            return s;
        }
        long h = 0L;
        try {
            Enumeration<NetworkInterface> ifcs =
                NetworkInterface.getNetworkInterfaces();
            if (ifcs.hasMoreElements()) {
                byte[] bs = ifcs.nextElement().getHardwareAddress();
                if (bs != null) {
                    for (int i = 0; i < 8 && i < bs.length; ++i)
                        h = (h << 8) ^ bs[i];
                }
            }
        } catch (Exception ignore) {
        }
        return (mix64(h ^ System.currentTimeMillis()) ^
                mix64(System.nanoTime()));




But not every interface has hardware address (loopback interface for example) and the order of returned interfaces is not defined. Also with security manager installed (System.setSecurityManager(new RMISecurityManager()) and no extra policy, the above code always evaluates 'h' to 0. The following is more robust (I included only the 2nd part after SecureRandom and added some prints to see what gets evaluated):

    public static long initialSeed() {
        long h = 0L;
        try {
h = AccessController.doPrivileged(new PrivilegedExceptionAction<Long>() {
                @Override
                public Long run() throws Exception {
                    long h = 0L;
                    Enumeration<NetworkInterface> ifcs =
NetworkInterface.getNetworkInterfaces();
                    while (ifcs.hasMoreElements()) {
                        NetworkInterface ifc = ifcs.nextElement();
                        System.out.println(ifc);
                        byte[] bs = ifc.getHardwareAddress();
System.out.println(Arrays.toString(bs));
                        if (bs != null) {
                            for (int i = 0; i < 8 && i < bs.length; ++i)
                                h = (h << 8) ^ bs[i];
                            break;
                        }
                    }
                    return h;
                }
            });
        } catch (Exception ignore) {
        }
        return (
            mix64(h ^ System.currentTimeMillis()) ^
            mix64(System.nanoTime())
        );
    }


Regards, Peter

Reply via email to