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.17 by jsr166, Tue Aug 13 23:34:47 2013 UTC vs.
Revision 1.18 by dl, Thu Aug 22 23:36:06 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 + *
88   * @author  Guy Steele
89   * @author  Doug Lea
90   * @since   1.8
# Line 138 | Line 146 | public class SplittableRandom {
146       * cases, this split must be performed in a thread-safe manner, so
147       * we use an AtomicLong to represent the seed rather than use an
148       * explicit SplittableRandom. To bootstrap the seeder, we start
149 <     * off using a seed based on current time and host. This serves as
150 <     * a slimmed-down (and insecure) variant of SecureRandom that also
149 >     * off using a seed based on current time and host unless the
150 >     * SecureRandomSeed property is set. This serves as a
151 >     * slimmed-down (and insecure) variant of SecureRandom that also
152       * avoids stalls that may occur when using /dev/random.
153       *
154       * It is a relatively simple matter to apply the basic design here
# Line 221 | Line 230 | public class SplittableRandom {
230      /**
231       * The seed generator for default constructors.
232       */
233 <    private static final AtomicLong seeder =
225 <        new AtomicLong(mix64((((long)hashedHostAddress()) << 32) ^
226 <                             System.currentTimeMillis()) ^
227 <                       mix64(System.nanoTime()));
233 >    private static final AtomicLong seeder = new AtomicLong(initialSeed());
234  
235 <    /**
236 <     * Returns hash of local host IP address, if available; else 0.
237 <     */
238 <    private static int hashedHostAddress() {
235 >    private static long initialSeed() {
236 >        try {  // ignore exceptions in accessing/parsing properties
237 >            String pp = System.getProperty
238 >                ("java.util.secureRandomSeed");
239 >            if (pp != null && pp.equalsIgnoreCase("true")) {
240 >                byte[] seedBytes = java.security.SecureRandom.getSeed(8);
241 >                long s = (long)(seedBytes[0]) & 0xffL;
242 >                for (int i = 1; i < 8; ++i)
243 >                    s = (s << 8) | ((long)(seedBytes[i]) & 0xffL);
244 >                return s;
245 >            }
246 >        } catch (Exception ignore) {
247 >        }
248 >        int hh = 0; // hashed host address
249          try {
250 <            return InetAddress.getLocalHost().hashCode();
251 <        } catch (Exception ex) {
236 <            return 0;
250 >            hh = InetAddress.getLocalHost().hashCode();
251 >        } catch (Exception ignore) {
252          }
253 +        return (mix64((((long)hh) << 32) ^ System.currentTimeMillis()) ^
254 +                mix64(System.nanoTime()));
255      }
256  
257      // IllegalArgumentException messages
# Line 406 | Line 423 | public class SplittableRandom {
423       * Returns a pseudorandom {@code int} value between zero (inclusive)
424       * and the specified bound (exclusive).
425       *
426 <     * @param bound the bound on the random number to be returned.  Must be
410 <     *        positive.
426 >     * @param bound the upper bound (exclusive).  Must be positive.
427       * @return a pseudorandom {@code int} value between zero
428       *         (inclusive) and the bound (exclusive)
429       * @throws IllegalArgumentException if {@code bound} is not positive
# Line 459 | Line 475 | public class SplittableRandom {
475       * Returns a pseudorandom {@code long} value between zero (inclusive)
476       * and the specified bound (exclusive).
477       *
478 <     * @param bound the bound on the random number to be returned.  Must be
463 <     *        positive.
478 >     * @param bound the upper bound (exclusive).  Must be positive.
479       * @return a pseudorandom {@code long} value between zero
480       *         (inclusive) and the bound (exclusive)
481       * @throws IllegalArgumentException if {@code bound} is not positive
# Line 504 | Line 519 | public class SplittableRandom {
519       * (inclusive) and one (exclusive).
520       *
521       * @return a pseudorandom {@code double} value between zero
522 <     * (inclusive) and one (exclusive)
522 >     *         (inclusive) and one (exclusive)
523       */
524      public double nextDouble() {
525          return (mix64(nextSeed()) >>> 11) * DOUBLE_UNIT;
# Line 514 | Line 529 | public class SplittableRandom {
529       * Returns a pseudorandom {@code double} value between 0.0
530       * (inclusive) and the specified bound (exclusive).
531       *
532 <     * @param bound the bound on the random number to be returned.  Must be
518 <     *        positive.
532 >     * @param bound the upper bound (exclusive).  Must be positive.
533       * @return a pseudorandom {@code double} value between zero
534       *         (inclusive) and the bound (exclusive)
535       * @throws IllegalArgumentException if {@code bound} is not positive
# Line 533 | Line 547 | public class SplittableRandom {
547       * origin (inclusive) and bound (exclusive).
548       *
549       * @param origin the least value returned
550 <     * @param bound the upper bound
550 >     * @param bound the upper bound (exclusive)
551       * @return a pseudorandom {@code double} value between the origin
552       *         (inclusive) and the bound (exclusive)
553       * @throws IllegalArgumentException if {@code origin} is greater than
# Line 594 | Line 608 | public class SplittableRandom {
608  
609      /**
610       * Returns a stream producing the given {@code streamSize} number
611 <     * of pseudorandom {@code int} values, each conforming to the
612 <     * given origin and bound.
611 >     * of pseudorandom {@code int} values from this generator and/or one split
612 >     * from it; each value conforms to the given origin (inclusive) and bound
613 >     * (exclusive).
614       *
615       * @param streamSize the number of values to generate
616 <     * @param randomNumberOrigin the origin of each random value
617 <     * @param randomNumberBound the bound of each random value
616 >     * @param randomNumberOrigin the origin (inclusive) of each random value
617 >     * @param randomNumberBound the bound (exclusive) of each random value
618       * @return a stream of pseudorandom {@code int} values,
619 <     *         each with the given origin and bound
619 >     *         each with the given origin (inclusive) and bound (exclusive)
620       * @throws IllegalArgumentException if {@code streamSize} is
621       *         less than zero, or {@code randomNumberOrigin}
622       *         is greater than or equal to {@code randomNumberBound}
# Line 620 | Line 635 | public class SplittableRandom {
635  
636      /**
637       * Returns an effectively unlimited stream of pseudorandom {@code
638 <     * int} values, each conforming to the given origin and bound.
638 >     * int} values from this generator and/or one split from it; each value
639 >     * conforms to the given origin (inclusive) and bound (exclusive).
640       *
641       * @implNote This method is implemented to be equivalent to {@code
642       * ints(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
643       *
644 <     * @param randomNumberOrigin the origin of each random value
645 <     * @param randomNumberBound the bound of each random value
644 >     * @param randomNumberOrigin the origin (inclusive) of each random value
645 >     * @param randomNumberBound the bound (exclusive) of each random value
646       * @return a stream of pseudorandom {@code int} values,
647 <     *         each with the given origin and bound
647 >     *         each with the given origin (inclusive) and bound (exclusive)
648       * @throws IllegalArgumentException if {@code randomNumberOrigin}
649       *         is greater than or equal to {@code randomNumberBound}
650       */
# Line 678 | Line 694 | public class SplittableRandom {
694  
695      /**
696       * Returns a stream producing the given {@code streamSize} number of
697 <     * pseudorandom {@code long} values, each conforming to the
698 <     * given origin and bound.
697 >     * pseudorandom {@code long} values from this generator and/or one split
698 >     * from it; each value conforms to the given origin (inclusive) and bound
699 >     * (exclusive).
700       *
701       * @param streamSize the number of values to generate
702 <     * @param randomNumberOrigin the origin of each random value
703 <     * @param randomNumberBound the bound of each random value
702 >     * @param randomNumberOrigin the origin (inclusive) of each random value
703 >     * @param randomNumberBound the bound (exclusive) of each random value
704       * @return a stream of pseudorandom {@code long} values,
705 <     *         each with the given origin and bound
705 >     *         each with the given origin (inclusive) and bound (exclusive)
706       * @throws IllegalArgumentException if {@code streamSize} is
707       *         less than zero, or {@code randomNumberOrigin}
708       *         is greater than or equal to {@code randomNumberBound}
# Line 704 | Line 721 | public class SplittableRandom {
721  
722      /**
723       * Returns an effectively unlimited stream of pseudorandom {@code
724 <     * long} values, each conforming to the given origin and bound.
724 >     * long} values from this generator and/or one split from it; each value
725 >     * conforms to the given origin (inclusive) and bound (exclusive).
726       *
727       * @implNote This method is implemented to be equivalent to {@code
728       * longs(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
729       *
730 <     * @param randomNumberOrigin the origin of each random value
731 <     * @param randomNumberBound the bound of each random value
730 >     * @param randomNumberOrigin the origin (inclusive) of each random value
731 >     * @param randomNumberBound the bound (exclusive) of each random value
732       * @return a stream of pseudorandom {@code long} values,
733 <     *         each with the given origin and bound
733 >     *         each with the given origin (inclusive) and bound (exclusive)
734       * @throws IllegalArgumentException if {@code randomNumberOrigin}
735       *         is greater than or equal to {@code randomNumberBound}
736       */
# Line 727 | Line 745 | public class SplittableRandom {
745  
746      /**
747       * Returns a stream producing the given {@code streamSize} number of
748 <     * pseudorandom {@code double} values, each between zero
749 <     * (inclusive) and one (exclusive).
748 >     * pseudorandom {@code double} values from this generator and/or one split
749 >     * from it; each value is between zero (inclusive) and one (exclusive).
750       *
751       * @param streamSize the number of values to generate
752       * @return a stream of {@code double} values
# Line 746 | Line 764 | public class SplittableRandom {
764  
765      /**
766       * Returns an effectively unlimited stream of pseudorandom {@code
767 <     * double} values, each between zero (inclusive) and one
768 <     * (exclusive).
767 >     * double} values from this generator and/or one split from it; each value
768 >     * is between zero (inclusive) and one (exclusive).
769       *
770       * @implNote This method is implemented to be equivalent to {@code
771       * doubles(Long.MAX_VALUE)}.
# Line 763 | Line 781 | public class SplittableRandom {
781  
782      /**
783       * Returns a stream producing the given {@code streamSize} number of
784 <     * pseudorandom {@code double} values, each conforming to the
785 <     * given origin and bound.
784 >     * pseudorandom {@code double} values from this generator and/or one split
785 >     * from it; each value conforms to the given origin (inclusive) and bound
786 >     * (exclusive).
787       *
788       * @param streamSize the number of values to generate
789 <     * @param randomNumberOrigin the origin of each random value
790 <     * @param randomNumberBound the bound of each random value
789 >     * @param randomNumberOrigin the origin (inclusive) of each random value
790 >     * @param randomNumberBound the bound (exclusive) of each random value
791       * @return a stream of pseudorandom {@code double} values,
792 <     * each with the given origin and bound
792 >     *         each with the given origin (inclusive) and bound (exclusive)
793       * @throws IllegalArgumentException if {@code streamSize} is
794 <     * less than zero
794 >     *         less than zero
795       * @throws IllegalArgumentException if {@code randomNumberOrigin}
796       *         is greater than or equal to {@code randomNumberBound}
797       */
# Line 790 | Line 809 | public class SplittableRandom {
809  
810      /**
811       * Returns an effectively unlimited stream of pseudorandom {@code
812 <     * double} values, each conforming to the given origin and bound.
812 >     * double} values from this generator and/or one split from it; each value
813 >     * conforms to the given origin (inclusive) and bound (exclusive).
814       *
815       * @implNote This method is implemented to be equivalent to {@code
816       * doubles(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
817       *
818 <     * @param randomNumberOrigin the origin of each random value
819 <     * @param randomNumberBound the bound of each random value
818 >     * @param randomNumberOrigin the origin (inclusive) of each random value
819 >     * @param randomNumberBound the bound (exclusive) of each random value
820       * @return a stream of pseudorandom {@code double} values,
821 <     * each with the given origin and bound
821 >     *         each with the given origin (inclusive) and bound (exclusive)
822       * @throws IllegalArgumentException if {@code randomNumberOrigin}
823       *         is greater than or equal to {@code randomNumberBound}
824       */

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines