View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.rng.simple;
18  
19  import org.apache.commons.rng.UniformRandomProvider;
20  
21  import java.util.Random;
22  
23  /**
24   * Wraps a {@link Random} instance to implement {@link UniformRandomProvider}. All methods from
25   * the {@code Random} that match those in {@code UniformRandomProvider} are used directly.
26   *
27   * <p>This class can be used to wrap an instance of
28   * {@link java.security.SecureRandom SecureRandom}. The {@code SecureRandom} class provides
29   * cryptographic random number generation. The features available depend on the Java version
30   * and platform. Consult the Java documentation for more details.</p>
31   *
32   * <p>Note: Use of {@code java.util.Random} is <em>not</em> recommended for applications.
33   * There are many other pseudo-random number generators that are statistically superior and often
34   * faster (see {@link RandomSource}).</p>
35   *
36   * @see java.security.SecureRandom
37   * @see RandomSource
38   * @since 1.3
39   */
40  public final class JDKRandomWrapper implements UniformRandomProvider {
41      /** The JDK Random instance. */
42      private final Random rng;
43  
44      /**
45       * Create a wrapper around a Random instance.
46       *
47       * @param rng JDK {@link Random} instance to which the random number
48       * generation is delegated.
49       */
50      public JDKRandomWrapper(Random rng) {
51          this.rng = rng;
52      }
53  
54      /** {@inheritDoc} */
55      @Override
56      public void nextBytes(byte[] bytes) {
57          rng.nextBytes(bytes);
58      }
59  
60      /** {@inheritDoc} */
61      @Override
62      public void nextBytes(byte[] bytes,
63                            int start,
64                            int len) {
65          final byte[] reduced = new byte[len];
66          rng.nextBytes(reduced);
67          System.arraycopy(reduced, 0, bytes, start, len);
68      }
69  
70      /** {@inheritDoc} */
71      @Override
72      public int nextInt() {
73          return rng.nextInt();
74      }
75  
76      /** {@inheritDoc} */
77      @Override
78      public int nextInt(int n) {
79          return rng.nextInt(n);
80      }
81  
82      /** {@inheritDoc} */
83      @Override
84      public long nextLong() {
85          return rng.nextLong();
86      }
87  
88      /** {@inheritDoc} */
89      @Override
90      public long nextLong(long n) {
91          // Code copied from "o.a.c.rng.core.BaseProvider".
92          if (n <= 0) {
93              throw new IllegalArgumentException("Must be strictly positive: " + n);
94          }
95  
96          long bits;
97          long val;
98          do {
99              bits = nextLong() >>> 1;
100             val  = bits % n;
101         } while (bits - val + (n - 1) < 0);
102 
103         return val;
104     }
105 
106     /** {@inheritDoc} */
107     @Override
108     public boolean nextBoolean() {
109         return rng.nextBoolean();
110     }
111 
112     /** {@inheritDoc} */
113     @Override
114     public float nextFloat() {
115         return rng.nextFloat();
116     }
117 
118     /** {@inheritDoc} */
119     @Override
120     public double nextDouble() {
121         return rng.nextDouble();
122     }
123 }