ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/SplittableRandom.java
(Generate patch)

Comparing jsr166/src/main/java/util/SplittableRandom.java (file contents):
Revision 1.16 by dl, Tue Aug 13 17:13:57 2013 UTC vs.
Revision 1.20 by jsr166, Sat Aug 24 06:20:15 2013 UTC

# Line 25 | Line 25
25  
26   package java.util;
27  
28 + import java.security.SecureRandom;
29   import java.net.InetAddress;
30   import java.util.concurrent.atomic.AtomicLong;
30 import java.util.Spliterator;
31   import java.util.function.IntConsumer;
32   import java.util.function.LongConsumer;
33   import java.util.function.DoubleConsumer;
# Line 39 | Line 39 | import java.util.stream.DoubleStream;
39   /**
40   * A generator of uniform pseudorandom values applicable for use in
41   * (among other contexts) isolated parallel computations that may
42 < * generate subtasks. Class SplittableRandom supports methods for
42 > * generate subtasks. Class {@code SplittableRandom} supports methods for
43   * producing pseudorandom numbers of type {@code int}, {@code long},
44   * and {@code double} with similar usages as for class
45   * {@link java.util.Random} but differs in the following ways:
# Line 77 | Line 77 | import java.util.stream.DoubleStream;
77   *
78   * </ul>
79   *
80 + * <p>Instances of {@code SplittableRandom} are not cryptographically
81 + * secure.  Consider instead using {@link java.security.SecureRandom}
82 + * in security-sensitive applications. Additionally,
83 + * default-constructed instances do not use a cryptographically random
84 + * seed unless the {@linkplain System#getProperty system property}
85 + * {@code java.util.secureRandomSeed} is set to {@code true}.
86 + *
87   * @author  Guy Steele
88   * @author  Doug Lea
89   * @since   1.8
# Line 138 | Line 145 | public class SplittableRandom {
145       * cases, this split must be performed in a thread-safe manner, so
146       * we use an AtomicLong to represent the seed rather than use an
147       * explicit SplittableRandom. To bootstrap the seeder, we start
148 <     * off using a seed based on current time and host. This serves as
149 <     * a slimmed-down (and insecure) variant of SecureRandom that also
148 >     * off using a seed based on current time and host unless the
149 >     * java.util.secureRandomSeed property is set. This serves as a
150 >     * slimmed-down (and insecure) variant of SecureRandom that also
151       * avoids stalls that may occur when using /dev/random.
152       *
153       * It is a relatively simple matter to apply the basic design here
# Line 221 | Line 229 | public class SplittableRandom {
229      /**
230       * The seed generator for default constructors.
231       */
232 <    private static final AtomicLong seeder =
225 <        new AtomicLong(mix64((((long)hashedHostAddress()) << 32) ^
226 <                             System.currentTimeMillis()) ^
227 <                       mix64(System.nanoTime()));
232 >    private static final AtomicLong seeder = new AtomicLong(initialSeed());
233  
234 <    /**
235 <     * Returns hash of local host IP address, if available; else 0.
236 <     */
237 <    private static int hashedHostAddress() {
238 <        try {
239 <            return InetAddress.getLocalHost().hashCode();
240 <        } catch (Exception ex) {
241 <            return 0;
242 <        }
234 >    private static long initialSeed() {
235 >        try {  // ignore exceptions in accessing/parsing properties
236 >            String pp = System.getProperty
237 >                ("java.util.secureRandomSeed");
238 >            if (pp != null && pp.equalsIgnoreCase("true")) {
239 >                byte[] seedBytes = java.security.SecureRandom.getSeed(8);
240 >                long s = (long)(seedBytes[0]) & 0xffL;
241 >                for (int i = 1; i < 8; ++i)
242 >                    s = (s << 8) | ((long)(seedBytes[i]) & 0xffL);
243 >                return s;
244 >            }
245 >        } catch (Exception ignore) {
246 >        }
247 >        int hh = 0; // hashed host address
248 >        try {
249 >            hh = InetAddress.getLocalHost().hashCode();
250 >        } catch (Exception ignore) {
251 >        }
252 >        return (mix64((((long)hh) << 32) ^ System.currentTimeMillis()) ^
253 >                mix64(System.nanoTime()));
254      }
255  
256      // IllegalArgumentException messages
# Line 406 | Line 422 | public class SplittableRandom {
422       * Returns a pseudorandom {@code int} value between zero (inclusive)
423       * and the specified bound (exclusive).
424       *
425 <     * @param bound the bound on the random number to be returned.  Must be
410 <     *        positive.
425 >     * @param bound the upper bound (exclusive).  Must be positive.
426       * @return a pseudorandom {@code int} value between zero
427       *         (inclusive) and the bound (exclusive)
428       * @throws IllegalArgumentException if {@code bound} is not positive
# Line 459 | Line 474 | public class SplittableRandom {
474       * Returns a pseudorandom {@code long} value between zero (inclusive)
475       * and the specified bound (exclusive).
476       *
477 <     * @param bound the bound on the random number to be returned.  Must be
463 <     *        positive.
477 >     * @param bound the upper bound (exclusive).  Must be positive.
478       * @return a pseudorandom {@code long} value between zero
479       *         (inclusive) and the bound (exclusive)
480       * @throws IllegalArgumentException if {@code bound} is not positive
# Line 504 | Line 518 | public class SplittableRandom {
518       * (inclusive) and one (exclusive).
519       *
520       * @return a pseudorandom {@code double} value between zero
521 <     * (inclusive) and one (exclusive)
521 >     *         (inclusive) and one (exclusive)
522       */
523      public double nextDouble() {
524          return (mix64(nextSeed()) >>> 11) * DOUBLE_UNIT;
# Line 514 | Line 528 | public class SplittableRandom {
528       * Returns a pseudorandom {@code double} value between 0.0
529       * (inclusive) and the specified bound (exclusive).
530       *
531 <     * @param bound the bound on the random number to be returned.  Must be
518 <     *        positive.
531 >     * @param bound the upper bound (exclusive).  Must be positive.
532       * @return a pseudorandom {@code double} value between zero
533       *         (inclusive) and the bound (exclusive)
534       * @throws IllegalArgumentException if {@code bound} is not positive
# Line 533 | Line 546 | public class SplittableRandom {
546       * origin (inclusive) and bound (exclusive).
547       *
548       * @param origin the least value returned
549 <     * @param bound the upper bound
549 >     * @param bound the upper bound (exclusive)
550       * @return a pseudorandom {@code double} value between the origin
551       *         (inclusive) and the bound (exclusive)
552       * @throws IllegalArgumentException if {@code origin} is greater than
# Line 594 | Line 607 | public class SplittableRandom {
607  
608      /**
609       * Returns a stream producing the given {@code streamSize} number
610 <     * of pseudorandom {@code int} values, each conforming to the
611 <     * given origin and bound.
610 >     * of pseudorandom {@code int} values from this generator and/or one split
611 >     * from it; each value conforms to the given origin (inclusive) and bound
612 >     * (exclusive).
613       *
614       * @param streamSize the number of values to generate
615 <     * @param randomNumberOrigin the origin of each random value
616 <     * @param randomNumberBound the bound of each random value
615 >     * @param randomNumberOrigin the origin (inclusive) of each random value
616 >     * @param randomNumberBound the bound (exclusive) of each random value
617       * @return a stream of pseudorandom {@code int} values,
618 <     *         each with the given origin and bound
618 >     *         each with the given origin (inclusive) and bound (exclusive)
619       * @throws IllegalArgumentException if {@code streamSize} is
620       *         less than zero, or {@code randomNumberOrigin}
621       *         is greater than or equal to {@code randomNumberBound}
# Line 620 | Line 634 | public class SplittableRandom {
634  
635      /**
636       * Returns an effectively unlimited stream of pseudorandom {@code
637 <     * int} values, each conforming to the given origin and bound.
637 >     * int} values from this generator and/or one split from it; each value
638 >     * conforms to the given origin (inclusive) and bound (exclusive).
639       *
640       * @implNote This method is implemented to be equivalent to {@code
641       * ints(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
642       *
643 <     * @param randomNumberOrigin the origin of each random value
644 <     * @param randomNumberBound the bound of each random value
643 >     * @param randomNumberOrigin the origin (inclusive) of each random value
644 >     * @param randomNumberBound the bound (exclusive) of each random value
645       * @return a stream of pseudorandom {@code int} values,
646 <     *         each with the given origin and bound
646 >     *         each with the given origin (inclusive) and bound (exclusive)
647       * @throws IllegalArgumentException if {@code randomNumberOrigin}
648       *         is greater than or equal to {@code randomNumberBound}
649       */
# Line 678 | Line 693 | public class SplittableRandom {
693  
694      /**
695       * Returns a stream producing the given {@code streamSize} number of
696 <     * pseudorandom {@code long} values, each conforming to the
697 <     * given origin and bound.
696 >     * pseudorandom {@code long} values from this generator and/or one split
697 >     * from it; each value conforms to the given origin (inclusive) and bound
698 >     * (exclusive).
699       *
700       * @param streamSize the number of values to generate
701 <     * @param randomNumberOrigin the origin of each random value
702 <     * @param randomNumberBound the bound of each random value
701 >     * @param randomNumberOrigin the origin (inclusive) of each random value
702 >     * @param randomNumberBound the bound (exclusive) of each random value
703       * @return a stream of pseudorandom {@code long} values,
704 <     *         each with the given origin and bound
704 >     *         each with the given origin (inclusive) and bound (exclusive)
705       * @throws IllegalArgumentException if {@code streamSize} is
706       *         less than zero, or {@code randomNumberOrigin}
707       *         is greater than or equal to {@code randomNumberBound}
# Line 704 | Line 720 | public class SplittableRandom {
720  
721      /**
722       * Returns an effectively unlimited stream of pseudorandom {@code
723 <     * long} values, each conforming to the given origin and bound.
723 >     * long} values from this generator and/or one split from it; each value
724 >     * conforms to the given origin (inclusive) and bound (exclusive).
725       *
726       * @implNote This method is implemented to be equivalent to {@code
727       * longs(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
728       *
729 <     * @param randomNumberOrigin the origin of each random value
730 <     * @param randomNumberBound the bound of each random value
729 >     * @param randomNumberOrigin the origin (inclusive) of each random value
730 >     * @param randomNumberBound the bound (exclusive) of each random value
731       * @return a stream of pseudorandom {@code long} values,
732 <     *         each with the given origin and bound
732 >     *         each with the given origin (inclusive) and bound (exclusive)
733       * @throws IllegalArgumentException if {@code randomNumberOrigin}
734       *         is greater than or equal to {@code randomNumberBound}
735       */
# Line 727 | Line 744 | public class SplittableRandom {
744  
745      /**
746       * Returns a stream producing the given {@code streamSize} number of
747 <     * pseudorandom {@code double} values, each between zero
748 <     * (inclusive) and one (exclusive).
747 >     * pseudorandom {@code double} values from this generator and/or one split
748 >     * from it; each value is between zero (inclusive) and one (exclusive).
749       *
750       * @param streamSize the number of values to generate
751       * @return a stream of {@code double} values
# Line 746 | Line 763 | public class SplittableRandom {
763  
764      /**
765       * Returns an effectively unlimited stream of pseudorandom {@code
766 <     * double} values, each between zero (inclusive) and one
767 <     * (exclusive).
766 >     * double} values from this generator and/or one split from it; each value
767 >     * is between zero (inclusive) and one (exclusive).
768       *
769       * @implNote This method is implemented to be equivalent to {@code
770       * doubles(Long.MAX_VALUE)}.
# Line 763 | Line 780 | public class SplittableRandom {
780  
781      /**
782       * Returns a stream producing the given {@code streamSize} number of
783 <     * pseudorandom {@code double} values, each conforming to the
784 <     * given origin and bound.
783 >     * pseudorandom {@code double} values from this generator and/or one split
784 >     * from it; each value conforms to the given origin (inclusive) and bound
785 >     * (exclusive).
786       *
787       * @param streamSize the number of values to generate
788 <     * @param randomNumberOrigin the origin of each random value
789 <     * @param randomNumberBound the bound of each random value
788 >     * @param randomNumberOrigin the origin (inclusive) of each random value
789 >     * @param randomNumberBound the bound (exclusive) of each random value
790       * @return a stream of pseudorandom {@code double} values,
791 <     * each with the given origin and bound
791 >     *         each with the given origin (inclusive) and bound (exclusive)
792       * @throws IllegalArgumentException if {@code streamSize} is
793 <     * less than zero
793 >     *         less than zero
794       * @throws IllegalArgumentException if {@code randomNumberOrigin}
795       *         is greater than or equal to {@code randomNumberBound}
796       */
# Line 790 | Line 808 | public class SplittableRandom {
808  
809      /**
810       * Returns an effectively unlimited stream of pseudorandom {@code
811 <     * double} values, each conforming to the given origin and bound.
811 >     * double} values from this generator and/or one split from it; each value
812 >     * conforms to the given origin (inclusive) and bound (exclusive).
813       *
814       * @implNote This method is implemented to be equivalent to {@code
815       * doubles(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
816       *
817 <     * @param randomNumberOrigin the origin of each random value
818 <     * @param randomNumberBound the bound of each random value
817 >     * @param randomNumberOrigin the origin (inclusive) of each random value
818 >     * @param randomNumberBound the bound (exclusive) of each random value
819       * @return a stream of pseudorandom {@code double} values,
820 <     * each with the given origin and bound
820 >     *         each with the given origin (inclusive) and bound (exclusive)
821       * @throws IllegalArgumentException if {@code randomNumberOrigin}
822       *         is greater than or equal to {@code randomNumberBound}
823       */

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines