001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.rng.simple;
018
019import org.apache.commons.rng.UniformRandomProvider;
020
021import java.util.Random;
022
023/**
024 * Wraps a {@link Random} instance to implement {@link UniformRandomProvider}. All methods from
025 * the {@code Random} that match those in {@code UniformRandomProvider} are used directly.
026 *
027 * <p>This class can be used to wrap an instance of
028 * {@link java.security.SecureRandom SecureRandom}. The {@code SecureRandom} class provides
029 * cryptographic random number generation. The features available depend on the Java version
030 * and platform. Consult the Java documentation for more details.</p>
031 *
032 * <p>Note: Use of {@code java.util.Random} is <em>not</em> recommended for applications.
033 * There are many other pseudo-random number generators that are statistically superior and often
034 * faster (see {@link RandomSource}).</p>
035 *
036 * @see java.security.SecureRandom
037 * @see RandomSource
038 * @since 1.3
039 */
040public final class JDKRandomWrapper implements UniformRandomProvider {
041    /** The JDK Random instance. */
042    private final Random rng;
043
044    /**
045     * Create a wrapper around a Random instance.
046     *
047     * @param rng JDK {@link Random} instance to which the random number
048     * generation is delegated.
049     */
050    public JDKRandomWrapper(Random rng) {
051        this.rng = rng;
052    }
053
054    /** {@inheritDoc} */
055    @Override
056    public void nextBytes(byte[] bytes) {
057        rng.nextBytes(bytes);
058    }
059
060    /** {@inheritDoc} */
061    @Override
062    public void nextBytes(byte[] bytes,
063                          int start,
064                          int len) {
065        final byte[] reduced = new byte[len];
066        rng.nextBytes(reduced);
067        System.arraycopy(reduced, 0, bytes, start, len);
068    }
069
070    /** {@inheritDoc} */
071    @Override
072    public int nextInt() {
073        return rng.nextInt();
074    }
075
076    /** {@inheritDoc} */
077    @Override
078    public int nextInt(int n) {
079        return rng.nextInt(n);
080    }
081
082    /** {@inheritDoc} */
083    @Override
084    public long nextLong() {
085        return rng.nextLong();
086    }
087
088    /** {@inheritDoc} */
089    @Override
090    public long nextLong(long n) {
091        // Code copied from "o.a.c.rng.core.BaseProvider".
092        if (n <= 0) {
093            throw new IllegalArgumentException("Must be strictly positive: " + n);
094        }
095
096        long bits;
097        long val;
098        do {
099            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}