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 * https://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.lang3;
18
19 import java.security.SecureRandom;
20 import java.security.Security;
21 import java.util.Random;
22 import java.util.concurrent.ThreadLocalRandom;
23 import java.util.function.Supplier;
24
25 /**
26 * Generates random {@link String}s.
27 * <p>
28 * Use {@link #secure()} to get the singleton instance based on {@link SecureRandom#SecureRandom()} which uses a secure random number generator implementing the
29 * default random number algorithm.
30 * </p>
31 * <p>
32 * Use {@link #secureStrong()} to get the singleton instance based on {@link SecureRandom#getInstanceStrong()} which uses an instance that was selected by using
33 * the algorithms/providers specified in the {@code securerandom.strongAlgorithms} {@link Security} property.
34 * </p>
35 * <p>
36 * Use {@link #insecure()} to get the singleton instance based on {@link ThreadLocalRandom#current()} <strong>which is not cryptographically secure</strong>. In addition,
37 * instances do not use a cryptographically random seed unless the {@linkplain System#getProperty system property} {@code java.util.secureRandomSeed} is set to
38 * {@code true}.
39 * </p>
40 * <p>
41 * Starting in version 3.17.0, the method {@link #secure()} uses {@link SecureRandom#SecureRandom()} instead of {@link SecureRandom#getInstanceStrong()}, and
42 * adds {@link #secureStrong()}.
43 * </p>
44 * <p>
45 * Starting in version 3.16.0, this class uses {@link #secure()} for static methods and adds {@link #insecure()}.
46 * </p>
47 * <p>
48 * Starting in version 3.15.0, this class uses {@link SecureRandom#getInstanceStrong()} for static methods.
49 * </p>
50 * <p>
51 * Before version 3.15.0, this class used {@link ThreadLocalRandom#current()} for static methods, which is not cryptographically secure.
52 * </p>
53 * <p>
54 * RandomStringUtils is intended for simple use cases. For more advanced use cases consider using Apache Commons Text's
55 * <a href= "https://commons.apache.org/proper/commons-text/javadocs/api-release/org/apache/commons/text/RandomStringGenerator.html"> RandomStringGenerator</a>
56 * instead.
57 * </p>
58 * <p>
59 * The Apache Commons project provides <a href="https://commons.apache.org/proper/commons-rng/">Commons RNG</a> dedicated to pseudo-random number generation,
60 * that may be a better choice for applications with more stringent requirements (performance and/or correctness).
61 * </p>
62 * <p>
63 * Note that <em>private high surrogate</em> characters are ignored. These are Unicode characters that fall between the values 56192 (db80) and 56319 (dbff) as
64 * we don't know how to handle them. High and low surrogates are correctly dealt with - that is if a high surrogate is randomly chosen, 55296 (d800) to 56191
65 * (db7f) then it is followed by a low surrogate. If a low surrogate is chosen, 56320 (dc00) to 57343 (dfff) then it is placed after a randomly chosen high
66 * surrogate.
67 * </p>
68 * <p>
69 * #ThreadSafe#
70 * </p>
71 *
72 * @see #secure()
73 * @see #secureStrong()
74 * @see #insecure()
75 * @see SecureRandom#SecureRandom()
76 * @see SecureRandom#getInstanceStrong()
77 * @see ThreadLocalRandom#current()
78 * @see RandomUtils
79 * @since 1.0
80 */
81 public class RandomStringUtils {
82
83 private static final Supplier<RandomUtils> SECURE_SUPPLIER = RandomUtils::secure;
84
85 private static RandomStringUtils INSECURE = new RandomStringUtils(RandomUtils::insecure);
86
87 private static RandomStringUtils SECURE = new RandomStringUtils(SECURE_SUPPLIER);
88
89 private static RandomStringUtils SECURE_STRONG = new RandomStringUtils(RandomUtils::secureStrong);
90
91 private static final char[] ALPHANUMERICAL_CHARS = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
92 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
93 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '0', '1',
94 '2', '3', '4', '5', '6', '7', '8', '9' };
95
96 private static final int ASCII_0 = '0';
97 private static final int ASCII_9 = '9';
98 private static final int ASCII_A = 'A';
99 private static final int ASCII_z = 'z';
100
101 private static final int CACHE_PADDING_BITS = 3;
102 private static final int BITS_TO_BYTES_DIVISOR = 5;
103 private static final int BASE_CACHE_SIZE_PADDING = 10;
104
105 /**
106 * Gets the singleton instance based on {@link ThreadLocalRandom#current()}; <b>which is not cryptographically
107 * secure</b>; use {@link #secure()} to use an algorithms/providers specified in the
108 * {@code securerandom.strongAlgorithms} {@link Security} property.
109 * <p>
110 * The method {@link ThreadLocalRandom#current()} is called on-demand.
111 * </p>
112 *
113 * @return the singleton instance based on {@link ThreadLocalRandom#current()}.
114 * @see ThreadLocalRandom#current()
115 * @see #secure()
116 * @since 3.16.0
117 */
118 public static RandomStringUtils insecure() {
119 return INSECURE;
120 }
121
122 /**
123 * Creates a random string whose length is the number of characters specified.
124 *
125 * <p>
126 * Characters will be chosen from the set of all characters.
127 * </p>
128 *
129 * @param count the length of random string to create.
130 * @return the random string.
131 * @throws IllegalArgumentException if {@code count} < 0.
132 * @deprecated Use {@link #next(int)} from {@link #secure()}, {@link #secureStrong()}, or {@link #insecure()}.
133 */
134 @Deprecated
135 public static String random(final int count) {
136 return secure().next(count);
137 }
138
139 /**
140 * Creates a random string whose length is the number of characters specified.
141 *
142 * <p>
143 * Characters will be chosen from the set of alpha-numeric characters as indicated by the arguments.
144 * </p>
145 *
146 * @param count the length of random string to create.
147 * @param letters if {@code true}, generated string may include alphabetic characters.
148 * @param numbers if {@code true}, generated string may include numeric characters.
149 * @return the random string.
150 * @throws IllegalArgumentException if {@code count} < 0.
151 * @deprecated Use {@link #next(int, boolean, boolean)} from {@link #secure()}, {@link #secureStrong()}, or {@link #insecure()}.
152 */
153 @Deprecated
154 public static String random(final int count, final boolean letters, final boolean numbers) {
155 return secure().next(count, letters, numbers);
156 }
157
158 /**
159 * Creates a random string whose length is the number of characters specified.
160 *
161 * <p>
162 * Characters will be chosen from the set of characters specified.
163 * </p>
164 *
165 * @param count the length of random string to create.
166 * @param chars the character array containing the set of characters to use, may be null.
167 * @return the random string.
168 * @throws IllegalArgumentException if {@code count} < 0.
169 * @deprecated Use {@link #next(int, char...)} from {@link #secure()}, {@link #secureStrong()}, or {@link #insecure()}.
170 */
171 @Deprecated
172 public static String random(final int count, final char... chars) {
173 return secure().next(count, chars);
174 }
175
176 /**
177 * Creates a random string whose length is the number of characters specified.
178 *
179 * <p>
180 * Characters will be chosen from the set of alpha-numeric characters as indicated by the arguments.
181 * </p>
182 *
183 * @param count the length of random string to create.
184 * @param start the position in set of chars to start at.
185 * @param end the position in set of chars to end before.
186 * @param letters if {@code true}, generated string may include alphabetic characters.
187 * @param numbers if {@code true}, generated string may include numeric characters.
188 * @return the random string.
189 * @throws IllegalArgumentException if {@code count} < 0.
190 * @deprecated Use {@link #next(int, int, int, boolean, boolean)} from {@link #secure()}, {@link #secureStrong()}, or {@link #insecure()}.
191 */
192 @Deprecated
193 public static String random(final int count, final int start, final int end, final boolean letters,
194 final boolean numbers) {
195 return secure().next(count, start, end, letters, numbers);
196 }
197
198 /**
199 * Creates a random string based on a variety of options, using default source of randomness.
200 *
201 * <p>
202 * This method has exactly the same semantics as {@link #random(int,int,int,boolean,boolean,char[],Random)}, but
203 * instead of using an externally supplied source of randomness, it uses the internal static {@link Random}
204 * instance.
205 * </p>
206 *
207 * @param count the length of random string to create.
208 * @param start the position in set of chars to start at.
209 * @param end the position in set of chars to end before.
210 * @param letters if {@code true}, generated string may include alphabetic characters.
211 * @param numbers if {@code true}, generated string may include numeric characters.
212 * @param chars the set of chars to choose randoms from. If {@code null}, then it will use the set of all chars.
213 * @return the random string.
214 * @throws ArrayIndexOutOfBoundsException if there are not {@code (end - start) + 1} characters in the set array.
215 * @throws IllegalArgumentException if {@code count} < 0.
216 * @deprecated Use {@link #next(int, int, int, boolean, boolean, char...)} from {@link #secure()}, {@link #secureStrong()}, or {@link #insecure()}.
217 */
218 @Deprecated
219 public static String random(final int count, final int start, final int end, final boolean letters,
220 final boolean numbers, final char... chars) {
221 return secure().next(count, start, end, letters, numbers, chars);
222 }
223
224 /**
225 * Creates a random string based on a variety of options, using supplied source of randomness.
226 *
227 * <p>
228 * If start and end are both {@code 0}, start and end are set to {@code ' '} and {@code 'z'}, the ASCII printable
229 * characters, will be used, unless letters and numbers are both {@code false}, in which case, start and end are set
230 * to {@code 0} and {@link Character#MAX_CODE_POINT}.
231 *
232 * <p>
233 * If set is not {@code null}, characters between start and end are chosen.
234 * </p>
235 *
236 * <p>
237 * This method accepts a user-supplied {@link Random} instance to use as a source of randomness. By seeding a single
238 * {@link Random} instance with a fixed seed and using it for each call, the same random sequence of strings can be
239 * generated repeatedly and predictably.
240 * </p>
241 *
242 * @param count the length of random string to create.
243 * @param start the position in set of chars to start at (inclusive).
244 * @param end the position in set of chars to end before (exclusive).
245 * @param letters if {@code true}, generated string may include alphabetic characters.
246 * @param numbers if {@code true}, generated string may include numeric characters.
247 * @param chars the set of chars to choose randoms from, must not be empty. If {@code null}, then it will use the
248 * set of all chars.
249 * @param random a source of randomness.
250 * @return the random string.
251 * @throws ArrayIndexOutOfBoundsException if there are not {@code (end - start) + 1} characters in the set array.
252 * @throws IllegalArgumentException if {@code count} < 0 or the provided chars array is empty.
253 * @since 2.0
254 */
255 public static String random(int count, int start, int end, final boolean letters, final boolean numbers,
256 final char[] chars, final Random random) {
257 if (count == 0) {
258 return StringUtils.EMPTY;
259 }
260 if (count < 0) {
261 throw new IllegalArgumentException("Requested random string length " + count + " is less than 0.");
262 }
263 if (chars != null && chars.length == 0) {
264 throw new IllegalArgumentException("The chars array must not be empty");
265 }
266
267 if (start == 0 && end == 0) {
268 if (chars != null) {
269 end = chars.length;
270 } else if (!letters && !numbers) {
271 end = Character.MAX_CODE_POINT;
272 } else {
273 end = 'z' + 1;
274 start = ' ';
275 }
276 } else if (end <= start) {
277 throw new IllegalArgumentException(
278 "Parameter end (" + end + ") must be greater than start (" + start + ")");
279 } else if (start < 0 || end < 0) {
280 throw new IllegalArgumentException("Character positions MUST be >= 0");
281 }
282
283 if (end > Character.MAX_CODE_POINT) {
284 // Technically, it should be `Character.MAX_CODE_POINT+1` as `end` is excluded
285 // But the character `Character.MAX_CODE_POINT` is private use, so it would anyway be excluded
286 end = Character.MAX_CODE_POINT;
287 }
288
289 // Optimizations and tests when chars == null and using ASCII characters (end <= 0x7f)
290 if (chars == null && end <= 0x7f) {
291 // Optimize generation of full alphanumerical characters
292 // Normally, we would need to pick a 7-bit integer, since gap = 'z' - '0' + 1 = 75 > 64
293 // In turn, this would make us reject the sampling with probability 1 - 62 / 2^7 > 1 / 2
294 // Instead we can pick directly from the right set of 62 characters, which requires
295 // picking a 6-bit integer and only rejecting with probability 2 / 64 = 1 / 32
296 if (letters && numbers && start <= ASCII_0 && end >= ASCII_z + 1) {
297 return random(count, 0, 0, false, false, ALPHANUMERICAL_CHARS, random);
298 }
299
300 if (numbers && end <= ASCII_0 || letters && end <= ASCII_A) {
301 throw new IllegalArgumentException(
302 "Parameter end (" + end + ") must be greater then (" + ASCII_0 + ") for generating digits "
303 + "or greater then (" + ASCII_A + ") for generating letters.");
304 }
305
306 // Optimize start and end when filtering by letters and/or numbers:
307 // The range provided may be too large since we filter anyway afterward.
308 // Note the use of Math.min/max (as opposed to setting start to '0' for example),
309 // since it is possible the range start/end excludes some of the letters/numbers,
310 // e.g., it is possible that start already is '1' when numbers = true, and start
311 // needs to stay equal to '1' in that case.
312 // Note that because of the above test, we will always have start < end
313 // even after this optimization.
314 if (letters && numbers) {
315 start = Math.max(ASCII_0, start);
316 end = Math.min(ASCII_z + 1, end);
317 } else if (numbers) {
318 // just numbers, no letters
319 start = Math.max(ASCII_0, start);
320 end = Math.min(ASCII_9 + 1, end);
321 } else if (letters) {
322 // just letters, no numbers
323 start = Math.max(ASCII_A, start);
324 end = Math.min(ASCII_z + 1, end);
325 }
326 }
327
328 final StringBuilder builder = new StringBuilder(count);
329 final int gap = end - start;
330 final int gapBits = Integer.SIZE - Integer.numberOfLeadingZeros(gap);
331 // The size of the cache we use is an heuristic:
332 // about twice the number of bytes required if no rejection
333 // Ideally the cache size depends on multiple factor, including the cost of generating x bytes
334 // of randomness as well as the probability of rejection. It is however not easy to know
335 // those values programmatically for the general case.
336 // Calculate cache size:
337 // 1. Multiply count by bits needed per character (gapBits)
338 // 2. Add padding bits (3) to handle partial bytes
339 // 3. Divide by 5 to convert to bytes (normally this would be by 8, dividing by 5 allows for about 60% extra space)
340 // 4. Add base padding (10) to handle small counts efficiently
341 // 5. Ensure we don't exceed Integer.MAX_VALUE / 5 + 10 to provide a good balance between overflow prevention and
342 // making the cache extremely large
343 final long desiredCacheSize = ((long) count * gapBits + CACHE_PADDING_BITS) / BITS_TO_BYTES_DIVISOR + BASE_CACHE_SIZE_PADDING;
344 final int cacheSize = (int) Math.min(desiredCacheSize, Integer.MAX_VALUE / BITS_TO_BYTES_DIVISOR + BASE_CACHE_SIZE_PADDING);
345 final CachedRandomBits arb = new CachedRandomBits(cacheSize, random);
346
347 while (count-- != 0) {
348 // Generate a random value between start (included) and end (excluded)
349 final int randomValue = arb.nextBits(gapBits) + start;
350 // Rejection sampling if value too large
351 if (randomValue >= end) {
352 count++;
353 continue;
354 }
355
356 final int codePoint;
357 if (chars == null) {
358 codePoint = randomValue;
359
360 switch (Character.getType(codePoint)) {
361 case Character.UNASSIGNED:
362 case Character.PRIVATE_USE:
363 case Character.SURROGATE:
364 count++;
365 continue;
366 }
367
368 } else {
369 codePoint = chars[randomValue];
370 }
371
372 final int numberOfChars = Character.charCount(codePoint);
373 if (count == 0 && numberOfChars > 1) {
374 count++;
375 continue;
376 }
377
378 if (letters && Character.isLetter(codePoint) || numbers && Character.isDigit(codePoint)
379 || !letters && !numbers) {
380 builder.appendCodePoint(codePoint);
381
382 if (numberOfChars == 2) {
383 count--;
384 }
385
386 } else {
387 count++;
388 }
389 }
390 return builder.toString();
391 }
392
393 /**
394 * Creates a random string whose length is the number of characters specified.
395 *
396 * <p>
397 * Characters will be chosen from the set of characters specified by the string, must not be empty. If null, the set
398 * of all characters is used.
399 * </p>
400 *
401 * @param count the length of random string to create.
402 * @param chars the String containing the set of characters to use, may be null, but must not be empty.
403 * @return the random string.
404 * @throws IllegalArgumentException if {@code count} < 0 or the string is empty.
405 * @deprecated Use {@link #next(int, String)} from {@link #secure()}, {@link #secureStrong()}, or {@link #insecure()}.
406 */
407 @Deprecated
408 public static String random(final int count, final String chars) {
409 return secure().next(count, chars);
410 }
411
412 /**
413 * Creates a random string whose length is the number of characters specified.
414 *
415 * <p>
416 * Characters will be chosen from the set of Latin alphabetic characters (a-z, A-Z).
417 * </p>
418 *
419 * @param count the length of random string to create.
420 * @return the random string.
421 * @throws IllegalArgumentException if {@code count} < 0.
422 * @deprecated Use {@link #nextAlphabetic(int)} from {@link #secure()}, {@link #secureStrong()}, or {@link #insecure()}.
423 */
424 @Deprecated
425 public static String randomAlphabetic(final int count) {
426 return secure().nextAlphabetic(count);
427 }
428
429 /**
430 * Creates a random string whose length is between the inclusive minimum and the exclusive maximum.
431 *
432 * <p>
433 * Characters will be chosen from the set of Latin alphabetic characters (a-z, A-Z).
434 * </p>
435 *
436 * @param minLengthInclusive the inclusive minimum length of the string to generate.
437 * @param maxLengthExclusive the exclusive maximum length of the string to generate.
438 * @return the random string.
439 * @since 3.5
440 * @deprecated Use {@link #nextAlphabetic(int, int)} from {@link #secure()}, {@link #secureStrong()}, or {@link #insecure()}.
441 */
442 @Deprecated
443 public static String randomAlphabetic(final int minLengthInclusive, final int maxLengthExclusive) {
444 return secure().nextAlphabetic(minLengthInclusive, maxLengthExclusive);
445 }
446
447 /**
448 * Creates a random string whose length is the number of characters specified.
449 *
450 * <p>
451 * Characters will be chosen from the set of Latin alphabetic characters (a-z, A-Z) and the digits 0-9.
452 * </p>
453 *
454 * @param count the length of random string to create.
455 * @return the random string.
456 * @throws IllegalArgumentException if {@code count} < 0.
457 * @deprecated Use {@link #nextAlphanumeric(int)} from {@link #secure()}, {@link #secureStrong()}, or {@link #insecure()}.
458 */
459 @Deprecated
460 public static String randomAlphanumeric(final int count) {
461 return secure().nextAlphanumeric(count);
462 }
463
464 /**
465 * Creates a random string whose length is between the inclusive minimum and the exclusive maximum.
466 *
467 * <p>
468 * Characters will be chosen from the set of Latin alphabetic characters (a-z, A-Z) and the digits 0-9.
469 * </p>
470 *
471 * @param minLengthInclusive the inclusive minimum length of the string to generate.
472 * @param maxLengthExclusive the exclusive maximum length of the string to generate.
473 * @return the random string.
474 * @since 3.5
475 * @deprecated Use {@link #nextAlphanumeric(int, int)} from {@link #secure()}, {@link #secureStrong()}, or {@link #insecure()}.
476 */
477 @Deprecated
478 public static String randomAlphanumeric(final int minLengthInclusive, final int maxLengthExclusive) {
479 return secure().nextAlphanumeric(minLengthInclusive, maxLengthExclusive);
480 }
481
482 /**
483 * Creates a random string whose length is the number of characters specified.
484 *
485 * <p>
486 * Characters will be chosen from the set of characters whose ASCII value is between {@code 32} and {@code 126}
487 * (inclusive).
488 * </p>
489 *
490 * @param count the length of random string to create.
491 * @return the random string.
492 * @throws IllegalArgumentException if {@code count} < 0.
493 * @deprecated Use {@link #nextAscii(int)} from {@link #secure()}, {@link #secureStrong()}, or {@link #insecure()}.
494 */
495 @Deprecated
496 public static String randomAscii(final int count) {
497 return secure().nextAscii(count);
498 }
499
500 /**
501 * Creates a random string whose length is between the inclusive minimum and the exclusive maximum.
502 *
503 * <p>
504 * Characters will be chosen from the set of characters whose ASCII value is between {@code 32} and {@code 126}
505 * (inclusive).
506 * </p>
507 *
508 * @param minLengthInclusive the inclusive minimum length of the string to generate.
509 * @param maxLengthExclusive the exclusive maximum length of the string to generate.
510 * @return the random string.
511 * @since 3.5
512 * @deprecated Use {@link #nextAscii(int, int)} from {@link #secure()}, {@link #secureStrong()}, or {@link #insecure()}.
513 */
514 @Deprecated
515 public static String randomAscii(final int minLengthInclusive, final int maxLengthExclusive) {
516 return secure().nextAscii(minLengthInclusive, maxLengthExclusive);
517 }
518
519 /**
520 * Creates a random string whose length is the number of characters specified.
521 *
522 * <p>
523 * Characters will be chosen from the set of characters which match the POSIX [:graph:] regular expression character
524 * class. This class contains all visible ASCII characters (i.e. anything except spaces and control characters).
525 * </p>
526 *
527 * @param count the length of random string to create.
528 * @return the random string.
529 * @throws IllegalArgumentException if {@code count} < 0.
530 * @since 3.5
531 * @deprecated Use {@link #nextGraph(int)} from {@link #secure()}, {@link #secureStrong()}, or {@link #insecure()}.
532 */
533 @Deprecated
534 public static String randomGraph(final int count) {
535 return secure().nextGraph(count);
536 }
537
538 /**
539 * Creates a random string whose length is between the inclusive minimum and the exclusive maximum.
540 *
541 * <p>
542 * Characters will be chosen from the set of \p{Graph} characters.
543 * </p>
544 *
545 * @param minLengthInclusive the inclusive minimum length of the string to generate.
546 * @param maxLengthExclusive the exclusive maximum length of the string to generate.
547 * @return the random string.
548 * @since 3.5
549 * @deprecated Use {@link #nextGraph(int, int)} from {@link #secure()}, {@link #secureStrong()}, or {@link #insecure()}.
550 */
551 @Deprecated
552 public static String randomGraph(final int minLengthInclusive, final int maxLengthExclusive) {
553 return secure().nextGraph(minLengthInclusive, maxLengthExclusive);
554 }
555
556 /**
557 * Creates a random string whose length is the number of characters specified.
558 *
559 * <p>
560 * Characters will be chosen from the set of numeric characters.
561 * </p>
562 *
563 * @param count the length of random string to create.
564 * @return the random string.
565 * @throws IllegalArgumentException if {@code count} < 0.
566 * @deprecated Use {@link #nextNumeric(int)} from {@link #secure()}, {@link #secureStrong()}, or {@link #insecure()}.
567 */
568 @Deprecated
569 public static String randomNumeric(final int count) {
570 return secure().nextNumeric(count);
571 }
572
573 /**
574 * Creates a random string whose length is between the inclusive minimum and the exclusive maximum.
575 *
576 * <p>
577 * Characters will be chosen from the set of \p{Digit} characters.
578 * </p>
579 *
580 * @param minLengthInclusive the inclusive minimum length of the string to generate.
581 * @param maxLengthExclusive the exclusive maximum length of the string to generate.
582 * @return the random string.
583 * @since 3.5
584 * @deprecated Use {@link #nextNumeric(int, int)} from {@link #secure()}, {@link #secureStrong()}, or {@link #insecure()}.
585 */
586 @Deprecated
587 public static String randomNumeric(final int minLengthInclusive, final int maxLengthExclusive) {
588 return secure().nextNumeric(minLengthInclusive, maxLengthExclusive);
589 }
590
591 /**
592 * Creates a random string whose length is the number of characters specified.
593 *
594 * <p>
595 * Characters will be chosen from the set of characters which match the POSIX [:print:] regular expression character
596 * class. This class includes all visible ASCII characters and spaces (i.e. anything except control characters).
597 * </p>
598 *
599 * @param count the length of random string to create.
600 * @return the random string.
601 * @throws IllegalArgumentException if {@code count} < 0.
602 * @since 3.5
603 * @deprecated Use {@link #randomPrint(int)} from {@link #secure()}, {@link #secureStrong()}, or {@link #insecure()}.
604 */
605 @Deprecated
606 public static String randomPrint(final int count) {
607 return secure().nextPrint(count);
608 }
609
610 /**
611 * Creates a random string whose length is between the inclusive minimum and the exclusive maximum.
612 *
613 * <p>
614 * Characters will be chosen from the set of \p{Print} characters.
615 * </p>
616 *
617 * @param minLengthInclusive the inclusive minimum length of the string to generate.
618 * @param maxLengthExclusive the exclusive maximum length of the string to generate.
619 * @return the random string.
620 * @since 3.5
621 * @deprecated Use {@link #randomPrint(int, int)} from {@link #secure()}, {@link #secureStrong()}, or {@link #insecure()}.
622 */
623 @Deprecated
624 public static String randomPrint(final int minLengthInclusive, final int maxLengthExclusive) {
625 return secure().nextPrint(minLengthInclusive, maxLengthExclusive);
626 }
627
628 /**
629 * Gets the singleton instance based on {@link SecureRandom#SecureRandom()} which uses a secure random number generator (RNG) implementing the default
630 * random number algorithm.
631 * <p>
632 * The method {@link SecureRandom#SecureRandom()} is called on-demand.
633 * </p>
634 *
635 * @return the singleton instance based on {@link SecureRandom#SecureRandom()}.
636 * @see SecureRandom#SecureRandom()
637 * @since 3.16.0
638 */
639 public static RandomStringUtils secure() {
640 return SECURE;
641 }
642
643 /**
644 * Gets the singleton instance based on {@link SecureRandom#getInstanceStrong()} which uses an algorithms/providers
645 * specified in the {@code securerandom.strongAlgorithms} {@link Security} property.
646 * <p>
647 * The method {@link SecureRandom#getInstanceStrong()} is called on-demand.
648 * </p>
649 *
650 * @return the singleton instance based on {@link SecureRandom#getInstanceStrong()}.
651 * @see SecureRandom#getInstanceStrong()
652 * @since 3.17.0
653 */
654 public static RandomStringUtils secureStrong() {
655 return SECURE_STRONG;
656 }
657
658 private final Supplier<RandomUtils> random;
659
660 /**
661 * {@link RandomStringUtils} instances should NOT be constructed in standard programming. Instead, the class should
662 * be used as {@code RandomStringUtils.random(5);}.
663 *
664 * <p>
665 * This constructor is public to permit tools that require a JavaBean instance to operate.
666 * </p>
667 *
668 * @deprecated TODO Make private in 4.0.
669 */
670 @Deprecated
671 public RandomStringUtils() {
672 this(SECURE_SUPPLIER);
673 }
674
675 private RandomStringUtils(final Supplier<RandomUtils> random) {
676 this.random = random;
677 }
678
679 /**
680 * Creates a random string whose length is the number of characters specified.
681 *
682 * <p>
683 * Characters will be chosen from the set of all characters.
684 * </p>
685 *
686 * @param count the length of random string to create.
687 * @return the random string.
688 * @throws IllegalArgumentException if {@code count} < 0.
689 * @since 3.16.0
690 */
691 public String next(final int count) {
692 return next(count, false, false);
693 }
694
695 /**
696 * Creates a random string whose length is the number of characters specified.
697 *
698 * <p>
699 * Characters will be chosen from the set of alpha-numeric characters as indicated by the arguments.
700 * </p>
701 *
702 * @param count the length of random string to create.
703 * @param letters if {@code true}, generated string may include alphabetic characters.
704 * @param numbers if {@code true}, generated string may include numeric characters.
705 * @return the random string.
706 * @throws IllegalArgumentException if {@code count} < 0.
707 * @since 3.16.0
708 */
709 public String next(final int count, final boolean letters, final boolean numbers) {
710 return next(count, 0, 0, letters, numbers);
711 }
712
713 /**
714 * Creates a random string whose length is the number of characters specified.
715 *
716 * <p>
717 * Characters will be chosen from the set of characters specified.
718 * </p>
719 *
720 * @param count the length of random string to create.
721 * @param chars the character array containing the set of characters to use, may be null.
722 * @return the random string.
723 * @throws IllegalArgumentException if {@code count} < 0.
724 * @since 3.16.0
725 */
726 public String next(final int count, final char... chars) {
727 if (chars == null) {
728 return random(count, 0, 0, false, false, null, random());
729 }
730 return random(count, 0, chars.length, false, false, chars, random());
731 }
732
733 /**
734 * Creates a random string whose length is the number of characters specified.
735 *
736 * <p>
737 * Characters will be chosen from the set of alpha-numeric characters as indicated by the arguments.
738 * </p>
739 *
740 * @param count the length of random string to create.
741 * @param start the position in set of chars to start at.
742 * @param end the position in set of chars to end before.
743 * @param letters if {@code true}, generated string may include alphabetic characters.
744 * @param numbers if {@code true}, generated string may include numeric characters.
745 * @return the random string.
746 * @throws IllegalArgumentException if {@code count} < 0.
747 * @since 3.16.0
748 */
749 public String next(final int count, final int start, final int end, final boolean letters, final boolean numbers) {
750 return random(count, start, end, letters, numbers, null, random());
751 }
752
753 /**
754 * Creates a random string based on a variety of options, using default source of randomness.
755 *
756 * <p>
757 * This method has exactly the same semantics as {@link #random(int,int,int,boolean,boolean,char[],Random)}, but
758 * instead of using an externally supplied source of randomness, it uses the internal static {@link Random}
759 * instance.
760 * </p>
761 *
762 * @param count the length of random string to create.
763 * @param start the position in set of chars to start at.
764 * @param end the position in set of chars to end before.
765 * @param letters if {@code true}, generated string may include alphabetic characters.
766 * @param numbers if {@code true}, generated string may include numeric characters.
767 * @param chars the set of chars to choose randoms from. If {@code null}, then it will use the set of all chars.
768 * @return the random string.
769 * @throws ArrayIndexOutOfBoundsException if there are not {@code (end - start) + 1} characters in the set array.
770 * @throws IllegalArgumentException if {@code count} < 0.
771 */
772 public String next(final int count, final int start, final int end, final boolean letters, final boolean numbers,
773 final char... chars) {
774 return random(count, start, end, letters, numbers, chars, random());
775 }
776
777 /**
778 * Creates a random string whose length is the number of characters specified.
779 *
780 * <p>
781 * Characters will be chosen from the set of characters specified by the string, must not be empty. If null, the set
782 * of all characters is used.
783 * </p>
784 *
785 * @param count the length of random string to create.
786 * @param chars the String containing the set of characters to use, may be null, but must not be empty.
787 * @return the random string.
788 * @throws IllegalArgumentException if {@code count} < 0 or the string is empty.
789 * @since 3.16.0
790 */
791 public String next(final int count, final String chars) {
792 if (chars == null) {
793 return random(count, 0, 0, false, false, null, random());
794 }
795 return next(count, chars.toCharArray());
796 }
797
798 /**
799 * Creates a random string whose length is the number of characters specified.
800 *
801 * <p>
802 * Characters will be chosen from the set of Latin alphabetic characters (a-z, A-Z).
803 * </p>
804 *
805 * @param count the length of random string to create.
806 * @return the random string.
807 * @throws IllegalArgumentException if {@code count} < 0.
808 */
809 public String nextAlphabetic(final int count) {
810 return next(count, true, false);
811 }
812
813 /**
814 * Creates a random string whose length is between the inclusive minimum and the exclusive maximum.
815 *
816 * <p>
817 * Characters will be chosen from the set of Latin alphabetic characters (a-z, A-Z).
818 * </p>
819 *
820 * @param minLengthInclusive the inclusive minimum length of the string to generate.
821 * @param maxLengthExclusive the exclusive maximum length of the string to generate.
822 * @return the random string.
823 * @since 3.5
824 */
825 public String nextAlphabetic(final int minLengthInclusive, final int maxLengthExclusive) {
826 return nextAlphabetic(randomUtils().randomInt(minLengthInclusive, maxLengthExclusive));
827 }
828
829 /**
830 * Creates a random string whose length is the number of characters specified.
831 *
832 * <p>
833 * Characters will be chosen from the set of Latin alphabetic characters (a-z, A-Z) and the digits 0-9.
834 * </p>
835 *
836 * @param count the length of random string to create.
837 * @return the random string.
838 * @throws IllegalArgumentException if {@code count} < 0.
839 */
840 public String nextAlphanumeric(final int count) {
841 return next(count, true, true);
842 }
843
844 /**
845 * Creates a random string whose length is between the inclusive minimum and the exclusive maximum.
846 *
847 * <p>
848 * Characters will be chosen from the set of Latin alphabetic characters (a-z, A-Z) and the digits 0-9.
849 * </p>
850 *
851 * @param minLengthInclusive the inclusive minimum length of the string to generate.
852 * @param maxLengthExclusive the exclusive maximum length of the string to generate.
853 * @return the random string.
854 * @since 3.5
855 */
856 public String nextAlphanumeric(final int minLengthInclusive, final int maxLengthExclusive) {
857 return nextAlphanumeric(randomUtils().randomInt(minLengthInclusive, maxLengthExclusive));
858 }
859
860 /**
861 * Creates a random string whose length is the number of characters specified.
862 *
863 * <p>
864 * Characters will be chosen from the set of characters whose ASCII value is between {@code 32} and {@code 126}
865 * (inclusive).
866 * </p>
867 *
868 * @param count the length of random string to create.
869 * @return the random string.
870 * @throws IllegalArgumentException if {@code count} < 0.
871 */
872 public String nextAscii(final int count) {
873 return next(count, 32, 127, false, false);
874 }
875
876 /**
877 * Creates a random string whose length is between the inclusive minimum and the exclusive maximum.
878 *
879 * <p>
880 * Characters will be chosen from the set of characters whose ASCII value is between {@code 32} and {@code 126}
881 * (inclusive).
882 * </p>
883 *
884 * @param minLengthInclusive the inclusive minimum length of the string to generate.
885 * @param maxLengthExclusive the exclusive maximum length of the string to generate.
886 * @return the random string.
887 * @since 3.5
888 */
889 public String nextAscii(final int minLengthInclusive, final int maxLengthExclusive) {
890 return nextAscii(randomUtils().randomInt(minLengthInclusive, maxLengthExclusive));
891 }
892
893 /**
894 * Creates a random string whose length is the number of characters specified.
895 *
896 * <p>
897 * Characters will be chosen from the set of characters which match the POSIX [:graph:] regular expression character
898 * class. This class contains all visible ASCII characters (i.e. anything except spaces and control characters).
899 * </p>
900 *
901 * @param count the length of random string to create.
902 * @return the random string.
903 * @throws IllegalArgumentException if {@code count} < 0.
904 * @since 3.5
905 */
906 public String nextGraph(final int count) {
907 return next(count, 33, 126, false, false);
908 }
909
910 /**
911 * Creates a random string whose length is between the inclusive minimum and the exclusive maximum.
912 *
913 * <p>
914 * Characters will be chosen from the set of \p{Graph} characters.
915 * </p>
916 *
917 * @param minLengthInclusive the inclusive minimum length of the string to generate.
918 * @param maxLengthExclusive the exclusive maximum length of the string to generate.
919 * @return the random string.
920 * @since 3.5
921 */
922 public String nextGraph(final int minLengthInclusive, final int maxLengthExclusive) {
923 return nextGraph(randomUtils().randomInt(minLengthInclusive, maxLengthExclusive));
924 }
925
926 /**
927 * Creates a random string whose length is the number of characters specified.
928 *
929 * <p>
930 * Characters will be chosen from the set of numeric characters.
931 * </p>
932 *
933 * @param count the length of random string to create.
934 * @return the random string.
935 * @throws IllegalArgumentException if {@code count} < 0.
936 */
937 public String nextNumeric(final int count) {
938 return next(count, false, true);
939 }
940
941 /**
942 * Creates a random string whose length is between the inclusive minimum and the exclusive maximum.
943 *
944 * <p>
945 * Characters will be chosen from the set of \p{Digit} characters.
946 * </p>
947 *
948 * @param minLengthInclusive the inclusive minimum length of the string to generate.
949 * @param maxLengthExclusive the exclusive maximum length of the string to generate.
950 * @return the random string.
951 * @since 3.5
952 */
953 public String nextNumeric(final int minLengthInclusive, final int maxLengthExclusive) {
954 return nextNumeric(randomUtils().randomInt(minLengthInclusive, maxLengthExclusive));
955 }
956
957 /**
958 * Creates a random string whose length is the number of characters specified.
959 *
960 * <p>
961 * Characters will be chosen from the set of characters which match the POSIX [:print:] regular expression character
962 * class. This class includes all visible ASCII characters and spaces (i.e. anything except control characters).
963 * </p>
964 *
965 * @param count the length of random string to create.
966 * @return the random string.
967 * @throws IllegalArgumentException if {@code count} < 0.
968 * @since 3.5
969 * @since 3.16.0
970 */
971 public String nextPrint(final int count) {
972 return next(count, 32, 126, false, false);
973 }
974
975 /**
976 * Creates a random string whose length is between the inclusive minimum and the exclusive maximum.
977 *
978 * <p>
979 * Characters will be chosen from the set of \p{Print} characters.
980 * </p>
981 *
982 * @param minLengthInclusive the inclusive minimum length of the string to generate.
983 * @param maxLengthExclusive the exclusive maximum length of the string to generate.
984 * @return the random string.
985 * @since 3.16.0
986 */
987 public String nextPrint(final int minLengthInclusive, final int maxLengthExclusive) {
988 return nextPrint(randomUtils().randomInt(minLengthInclusive, maxLengthExclusive));
989 }
990
991 /**
992 * Gets the Random.
993 *
994 * @return the Random.
995 */
996 private Random random() {
997 return randomUtils().random();
998 }
999
1000 /**
1001 * Gets the RandomUtils.
1002 *
1003 * @return the RandomUtils.
1004 */
1005 private RandomUtils randomUtils() {
1006 return random.get();
1007 }
1008
1009 @Override
1010 public String toString() {
1011 return "RandomStringUtils [random=" + random() + "]";
1012 }
1013
1014 }