    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}