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