RFR 8024253: ThreadLocal random can use SecureRandom for the initial seed

Martin Buchholz martinrb at google.com
Tue Sep 24 07:16:25 UTC 2013


Stupid SplittableRandom tricks:

            System.out.println(sr.nextDouble(0.0d,
Double.POSITIVE_INFINITY));
always prints constant 1.7976931348623157E308

which might be considered a bug.

---

The spec below fails to be pedantically correct when one of the args is NaN.

* @throws IllegalArgumentException if {@code origin} is greater than
     *         or equal to {@code bound}
     */
    public double nextDouble(double origin, double bound) {

Better to draw inspiration from the spec for
     * @throws IllegalArgumentException if {@code bound} is not positive
     */
    public double nextDouble(double bound) {

and write:

     * @throws IllegalArgumentException if {@code bound - origin} is not
positive
     */
    public double nextDouble(double origin, double bound) {



On Mon, Sep 16, 2013 at 4:22 PM, Doug Lea <dl at cs.oswego.edu> wrote:

> On 09/16/2013 02:11 PM, Guy Steele wrote:
>
>  Okay, as long as we're obsessing: the code defends against the hardware
>> address being longer than 8 bytes.
>>
>
> This was to protect ourselves from the impact of this code being used in
> some
> alternative universe in which hardware addresses are not always 48bits.
> But you are right that we could do a little better.
>
>  So how about this code?
>> ...
>>
>>                            h = (h << 16) ^ (bs[i] << 8) ^ bs[n-1-i];
>>
>
> On first glance the sign extension of byte to long conversion
> makes this suspicious, but I see that it cannot hurt.
> So, sure; thanks.
>
> Here's the full current version, including another minor tweak.
> (Paul: I'm committing to our CVS.)
>
>
>     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();
>             boolean retry = false; // retry once if getHardwareAddress is
> null
>             while (ifcs.hasMoreElements()) {
>                 NetworkInterface ifc = ifcs.nextElement();
>                 if (!ifc.isVirtual()) { // skip fake addresses
>                     byte[] bs = ifc.getHardwareAddress();
>                     if (bs != null) {
>                         int n = bs.length;
>                         int m = Math.min(n >>> 1, 4);
>
>                         for (int i = 0; i < m; ++i)
>                             h = (h << 16) ^ (bs[i] << 8) ^ bs[n-1-i];
>                         if (m < 4)
>                             h = (h << 8) ^ bs[n-1-m];
>                         h = mix64(h);
>
>                         break;
>                     }
>                     else if (!retry)
>                         retry = true;
>                     else
>                         break;
>                 }
>             }
>         } catch (Exception ignore) {
>         }
>         return (h ^ mix64(System.**currentTimeMillis()) ^
>                 mix64(System.nanoTime()));
>     }
>
>



More information about the core-libs-dev mailing list