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.lang3;
018
019import java.util.Random;
020
021/**
022 * Utility library that supplements the standard {@link Random} class.
023 *
024 * <p>Please note that the Apache Commons project provides a component
025 * dedicated to pseudo-random number generation, namely
026 * <a href="https://commons.apache.org/proper/commons-rng/">Commons RNG</a>, that may be
027 * a better choice for applications with more stringent requirements
028 * (performance and/or correctness).</p>
029 *
030 * @deprecated Use Apache Commons RNG's optimized <a href="https://commons.apache.org/proper/commons-rng/commons-rng-client-api/apidocs/org/apache/commons/rng/UniformRandomProvider.html">UniformRandomProvider</a>
031 * @since 3.3
032 */
033@Deprecated
034public class RandomUtils {
035
036    /**
037     * Generates a random boolean value.
038     *
039     * @return the random boolean
040     * @since 3.5
041     */
042    public static boolean nextBoolean() {
043        return RandomStringUtils.random().nextBoolean();
044    }
045
046    /**
047     * Generates an array of random bytes.
048     *
049     * @param count
050     *            the size of the returned array
051     * @return the random byte array
052     * @throws IllegalArgumentException if {@code count} is negative
053     */
054    public static byte[] nextBytes(final int count) {
055        Validate.isTrue(count >= 0, "Count cannot be negative.");
056        final byte[] result = new byte[count];
057        RandomStringUtils.random().nextBytes(result);
058        return result;
059    }
060
061    /**
062     * Generates a random double between 0 (inclusive) and Double.MAX_VALUE (exclusive).
063     *
064     * @return the random double
065     * @see #nextDouble(double, double)
066     * @since 3.5
067     */
068    public static double nextDouble() {
069        return nextDouble(0, Double.MAX_VALUE);
070    }
071
072    /**
073     * Generates a random double within the specified range.
074     *
075     * @param startInclusive
076     *            the smallest value that can be returned, must be non-negative
077     * @param endExclusive
078     *            the upper bound (not included)
079     * @throws IllegalArgumentException
080     *             if {@code startInclusive > endExclusive} or if
081     *             {@code startInclusive} is negative
082     * @return the random double
083     */
084    public static double nextDouble(final double startInclusive, final double endExclusive) {
085        Validate.isTrue(endExclusive >= startInclusive,
086                "Start value must be smaller or equal to end value.");
087        Validate.isTrue(startInclusive >= 0, "Both range values must be non-negative.");
088        if (startInclusive == endExclusive) {
089            return startInclusive;
090        }
091        return startInclusive + (endExclusive - startInclusive) * RandomStringUtils.random().nextDouble();
092    }
093
094    /**
095     * Generates a random float between 0 (inclusive) and Float.MAX_VALUE (exclusive).
096     *
097     * @return the random float
098     * @see #nextFloat(float, float)
099     * @since 3.5
100     */
101    public static float nextFloat() {
102        return nextFloat(0, Float.MAX_VALUE);
103    }
104
105    /**
106     * Generates a random float within the specified range.
107     *
108     * @param startInclusive
109     *            the smallest value that can be returned, must be non-negative
110     * @param endExclusive
111     *            the upper bound (not included)
112     * @throws IllegalArgumentException
113     *             if {@code startInclusive > endExclusive} or if
114     *             {@code startInclusive} is negative
115     * @return the random float
116     */
117    public static float nextFloat(final float startInclusive, final float endExclusive) {
118        Validate.isTrue(endExclusive >= startInclusive,
119                "Start value must be smaller or equal to end value.");
120        Validate.isTrue(startInclusive >= 0, "Both range values must be non-negative.");
121        if (startInclusive == endExclusive) {
122            return startInclusive;
123        }
124        return startInclusive + (endExclusive - startInclusive) * RandomStringUtils.random().nextFloat();
125    }
126
127    /**
128     * Generates a random int between 0 (inclusive) and Integer.MAX_VALUE (exclusive).
129     *
130     * @return the random integer
131     * @see #nextInt(int, int)
132     * @since 3.5
133     */
134    public static int nextInt() {
135        return nextInt(0, Integer.MAX_VALUE);
136    }
137
138    /**
139     * Generates a random integer within the specified range.
140     *
141     * @param startInclusive
142     *            the smallest value that can be returned, must be non-negative
143     * @param endExclusive
144     *            the upper bound (not included)
145     * @throws IllegalArgumentException
146     *             if {@code startInclusive > endExclusive} or if
147     *             {@code startInclusive} is negative
148     * @return the random integer
149     */
150    public static int nextInt(final int startInclusive, final int endExclusive) {
151        Validate.isTrue(endExclusive >= startInclusive,
152                "Start value must be smaller or equal to end value.");
153        Validate.isTrue(startInclusive >= 0, "Both range values must be non-negative.");
154        if (startInclusive == endExclusive) {
155            return startInclusive;
156        }
157        return startInclusive + RandomStringUtils.random().nextInt(endExclusive - startInclusive);
158    }
159
160    /**
161     * Generates a random long between 0 (inclusive) and Long.MAX_VALUE (exclusive).
162     *
163     * @return the random long
164     * @see #nextLong(long, long)
165     * @since 3.5
166     */
167    public static long nextLong() {
168        return nextLong(Long.MAX_VALUE);
169    }
170
171    /**
172     * Generates a {@code long} value between 0 (inclusive) and the specified
173     * value (exclusive).
174     *
175     * @param n Bound on the random number to be returned.  Must be positive.
176     * @return a random {@code long} value between 0 (inclusive) and {@code n}
177     * (exclusive).
178     */
179    private static long nextLong(final long n) {
180        // Extracted from o.a.c.rng.core.BaseProvider.nextLong(long)
181        long bits;
182        long val;
183        do {
184            bits = RandomStringUtils.random().nextLong() >>> 1;
185            val  = bits % n;
186        } while (bits - val + n - 1 < 0);
187        return val;
188    }
189
190    /**
191     * Generates a random long within the specified range.
192     *
193     * @param startInclusive
194     *            the smallest value that can be returned, must be non-negative
195     * @param endExclusive
196     *            the upper bound (not included)
197     * @throws IllegalArgumentException
198     *             if {@code startInclusive > endExclusive} or if
199     *             {@code startInclusive} is negative
200     * @return the random long
201     */
202    public static long nextLong(final long startInclusive, final long endExclusive) {
203        Validate.isTrue(endExclusive >= startInclusive,
204                "Start value must be smaller or equal to end value.");
205        Validate.isTrue(startInclusive >= 0, "Both range values must be non-negative.");
206        if (startInclusive == endExclusive) {
207            return startInclusive;
208        }
209        return startInclusive + nextLong(endExclusive - startInclusive);
210    }
211
212    /**
213     * {@link RandomUtils} instances should NOT be constructed in standard
214     * programming. Instead, the class should be used as
215     * {@code RandomUtils.nextBytes(5);}.
216     * <p>
217     * This constructor is public to permit tools that require a JavaBean
218     * instance to operate.
219     * </p>
220     *
221     * @deprecated TODO Make private in 4.0.
222     */
223    @Deprecated
224    public RandomUtils() {
225        // empty
226    }
227}