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 final RandomStringUtils INSECURE = new RandomStringUtils(RandomUtils::insecure);
86
87 private static final RandomStringUtils SECURE = new RandomStringUtils(SECURE_SUPPLIER);
88
89 private static final 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>; for more secure processing use {@link #secure()} or {@link #secureStrong()}.
108 * <p>
109 * The method {@link ThreadLocalRandom#current()} is called on-demand.
110 * </p>
111 *
112 * @return the singleton instance based on {@link ThreadLocalRandom#current()}.
113 * @see ThreadLocalRandom#current()
114 * @see #secure()
115 * @see #secureStrong()
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 digits if {@code true}, generated string may include digit 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 digits,
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 if (start == 0 && end == 0) {
267 if (chars != null) {
268 end = chars.length;
269 } else if (!letters && !digits) {
270 end = Character.MAX_CODE_POINT;
271 } else {
272 end = 'z' + 1;
273 start = ' ';
274 }
275 } else if (end <= start) {
276 throw new IllegalArgumentException("Parameter end (" + end + ") must be greater than start (" + start + ")");
277 } else if (start < 0 || end < 0) {
278 throw new IllegalArgumentException("Character positions MUST be >= 0");
279 }
280 if (end > Character.MAX_CODE_POINT) {
281 // Technically, it should be `Character.MAX_CODE_POINT+1` as `end` is excluded
282 // But the character `Character.MAX_CODE_POINT` is private use, so it would anyway be excluded
283 end = Character.MAX_CODE_POINT;
284 }
285 // Optimizations and tests when chars == null and using ASCII characters (end <= 0x7f)
286 if (chars == null && end <= 0x7f) {
287 // Optimize generation of full alphanumerical characters
288 // Normally, we would need to pick a 7-bit integer, since gap = 'z' - '0' + 1 = 75 > 64
289 // In turn, this would make us reject the sampling with probability 1 - 62 / 2^7 > 1 / 2
290 // Instead we can pick directly from the right set of 62 characters, which requires
291 // picking a 6-bit integer and only rejecting with probability 2 / 64 = 1 / 32
292 if (letters && digits && start <= ASCII_0 && end >= ASCII_z + 1) {
293 return random(count, 0, 0, false, false, ALPHANUMERICAL_CHARS, random);
294 }
295 if (digits && end <= ASCII_0 || letters && end <= ASCII_A) {
296 throw new IllegalArgumentException("Parameter end (" + end + ") must be greater than (" + ASCII_0 + ") for generating digits "
297 + "or greater than (" + ASCII_A + ") for generating letters.");
298 }
299 // Optimize start and end when filtering by letters and/or numbers:
300 // The range provided may be too large since we filter anyway afterward.
301 // Note the use of Math.min/max (as opposed to setting start to '0' for example),
302 // since it is possible the range start/end excludes some of the letters/numbers,
303 // e.g., it is possible that start already is '1' when numbers = true, and start
304 // needs to stay equal to '1' in that case.
305 // Note that because of the above test, we will always have start < end
306 // even after this optimization.
307 if (letters && digits) {
308 start = Math.max(ASCII_0, start);
309 end = Math.min(ASCII_z + 1, end);
310 } else if (digits) {
311 // just numbers, no letters
312 start = Math.max(ASCII_0, start);
313 end = Math.min(ASCII_9 + 1, end);
314 } else if (letters) {
315 // just letters, no numbers
316 start = Math.max(ASCII_A, start);
317 end = Math.min(ASCII_z + 1, end);
318 }
319 }
320 if (letters && !digits) {
321 for (int i = start; i < end; i++) {
322 if (Character.isLetter(i)) {
323 break;
324 }
325 if (i == end - 1) {
326 throw new IllegalArgumentException(String.format("No letters exist between start %,d and end %,d.", start, end));
327 }
328 }
329 }
330 if (!letters && digits) {
331 for (int i = start; i < end; i++) {
332 if (Character.isDigit(i)) {
333 break;
334 }
335 if (i == end - 1) {
336 throw new IllegalArgumentException(String.format("No digits exist between start %,d and end %,d.", start, end));
337 }
338 }
339 }
340 final StringBuilder builder = new StringBuilder(count);
341 final int gap = end - start;
342 final int gapBits = Integer.SIZE - Integer.numberOfLeadingZeros(gap);
343 // The size of the cache we use is an heuristic:
344 // about twice the number of bytes required if no rejection
345 // Ideally the cache size depends on multiple factor, including the cost of generating x bytes
346 // of randomness as well as the probability of rejection. It is however not easy to know
347 // those values programmatically for the general case.
348 // Calculate cache size:
349 // 1. Multiply count by bits needed per character (gapBits)
350 // 2. Add padding bits (3) to handle partial bytes
351 // 3. Divide by 5 to convert to bytes (normally this would be by 8, dividing by 5 allows for about 60% extra space)
352 // 4. Add base padding (10) to handle small counts efficiently
353 // 5. Ensure we don't exceed Integer.MAX_VALUE / 5 + 10 to provide a good balance between overflow prevention and
354 // making the cache extremely large
355 final long desiredCacheSize = ((long) count * gapBits + CACHE_PADDING_BITS) / BITS_TO_BYTES_DIVISOR + BASE_CACHE_SIZE_PADDING;
356 final int cacheSize = (int) Math.min(desiredCacheSize, Integer.MAX_VALUE / BITS_TO_BYTES_DIVISOR + BASE_CACHE_SIZE_PADDING);
357 final CachedRandomBits arb = new CachedRandomBits(cacheSize, random);
358 while (count-- != 0) {
359 // Generate a random value between start (included) and end (excluded)
360 final int randomValue = arb.nextBits(gapBits) + start;
361 // Rejection sampling if value too large
362 if (randomValue >= end) {
363 count++;
364 continue;
365 }
366 final int codePoint;
367 if (chars == null) {
368 codePoint = randomValue;
369 switch (Character.getType(codePoint)) {
370 case Character.UNASSIGNED:
371 case Character.PRIVATE_USE:
372 case Character.SURROGATE:
373 count++;
374 continue;
375 }
376 } else {
377 codePoint = chars[randomValue];
378 }
379 final int numberOfChars = Character.charCount(codePoint);
380 if (count == 0 && numberOfChars > 1) {
381 count++;
382 continue;
383 }
384 if (letters && Character.isLetter(codePoint) || digits && Character.isDigit(codePoint) || !letters && !digits) {
385 builder.appendCodePoint(codePoint);
386 if (numberOfChars == 2) {
387 count--;
388 }
389 } else {
390 count++;
391 }
392 }
393 return builder.toString();
394 }
395
396 /**
397 * Creates a random string whose length is the number of characters specified.
398 *
399 * <p>
400 * Characters will be chosen from the set of characters specified by the string, must not be empty. If null, the set
401 * of all characters is used.
402 * </p>
403 *
404 * @param count the length of random string to create.
405 * @param chars the String containing the set of characters to use, may be null, but must not be empty.
406 * @return the random string.
407 * @throws IllegalArgumentException if {@code count} < 0 or the string is empty.
408 * @deprecated Use {@link #next(int, String)} from {@link #secure()}, {@link #secureStrong()}, or {@link #insecure()}.
409 */
410 @Deprecated
411 public static String random(final int count, final String chars) {
412 return secure().next(count, chars);
413 }
414
415 /**
416 * Creates a random string whose length is the number of characters specified.
417 *
418 * <p>
419 * Characters will be chosen from the set of Latin alphabetic characters (a-z, A-Z).
420 * </p>
421 *
422 * @param count the length of random string to create.
423 * @return the random string.
424 * @throws IllegalArgumentException if {@code count} < 0.
425 * @deprecated Use {@link #nextAlphabetic(int)} from {@link #secure()}, {@link #secureStrong()}, or {@link #insecure()}.
426 */
427 @Deprecated
428 public static String randomAlphabetic(final int count) {
429 return secure().nextAlphabetic(count);
430 }
431
432 /**
433 * Creates a random string whose length is between the inclusive minimum and the exclusive maximum.
434 *
435 * <p>
436 * Characters will be chosen from the set of Latin alphabetic characters (a-z, A-Z).
437 * </p>
438 *
439 * @param minLengthInclusive the inclusive minimum length of the string to generate.
440 * @param maxLengthExclusive the exclusive maximum length of the string to generate.
441 * @return the random string.
442 * @since 3.5
443 * @deprecated Use {@link #nextAlphabetic(int, int)} from {@link #secure()}, {@link #secureStrong()}, or {@link #insecure()}.
444 */
445 @Deprecated
446 public static String randomAlphabetic(final int minLengthInclusive, final int maxLengthExclusive) {
447 return secure().nextAlphabetic(minLengthInclusive, maxLengthExclusive);
448 }
449
450 /**
451 * Creates a random string whose length is the number of characters specified.
452 *
453 * <p>
454 * Characters will be chosen from the set of Latin alphabetic characters (a-z, A-Z) and the digits 0-9.
455 * </p>
456 *
457 * @param count the length of random string to create.
458 * @return the random string.
459 * @throws IllegalArgumentException if {@code count} < 0.
460 * @deprecated Use {@link #nextAlphanumeric(int)} from {@link #secure()}, {@link #secureStrong()}, or {@link #insecure()}.
461 */
462 @Deprecated
463 public static String randomAlphanumeric(final int count) {
464 return secure().nextAlphanumeric(count);
465 }
466
467 /**
468 * Creates a random string whose length is between the inclusive minimum and the exclusive maximum.
469 *
470 * <p>
471 * Characters will be chosen from the set of Latin alphabetic characters (a-z, A-Z) and the digits 0-9.
472 * </p>
473 *
474 * @param minLengthInclusive the inclusive minimum length of the string to generate.
475 * @param maxLengthExclusive the exclusive maximum length of the string to generate.
476 * @return the random string.
477 * @since 3.5
478 * @deprecated Use {@link #nextAlphanumeric(int, int)} from {@link #secure()}, {@link #secureStrong()}, or {@link #insecure()}.
479 */
480 @Deprecated
481 public static String randomAlphanumeric(final int minLengthInclusive, final int maxLengthExclusive) {
482 return secure().nextAlphanumeric(minLengthInclusive, maxLengthExclusive);
483 }
484
485 /**
486 * Creates a random string whose length is the number of characters specified.
487 *
488 * <p>
489 * Characters will be chosen from the set of characters whose ASCII value is between {@code 32} and {@code 126}
490 * (inclusive).
491 * </p>
492 *
493 * @param count the length of random string to create.
494 * @return the random string.
495 * @throws IllegalArgumentException if {@code count} < 0.
496 * @deprecated Use {@link #nextAscii(int)} from {@link #secure()}, {@link #secureStrong()}, or {@link #insecure()}.
497 */
498 @Deprecated
499 public static String randomAscii(final int count) {
500 return secure().nextAscii(count);
501 }
502
503 /**
504 * Creates a random string whose length is between the inclusive minimum and the exclusive maximum.
505 *
506 * <p>
507 * Characters will be chosen from the set of characters whose ASCII value is between {@code 32} and {@code 126}
508 * (inclusive).
509 * </p>
510 *
511 * @param minLengthInclusive the inclusive minimum length of the string to generate.
512 * @param maxLengthExclusive the exclusive maximum length of the string to generate.
513 * @return the random string.
514 * @since 3.5
515 * @deprecated Use {@link #nextAscii(int, int)} from {@link #secure()}, {@link #secureStrong()}, or {@link #insecure()}.
516 */
517 @Deprecated
518 public static String randomAscii(final int minLengthInclusive, final int maxLengthExclusive) {
519 return secure().nextAscii(minLengthInclusive, maxLengthExclusive);
520 }
521
522 /**
523 * Creates a random string whose length is the number of characters specified.
524 *
525 * <p>
526 * Characters will be chosen from the set of characters which match the POSIX [:graph:] regular expression character
527 * class. This class contains all visible ASCII characters (i.e. anything except spaces and control characters).
528 * </p>
529 *
530 * @param count the length of random string to create.
531 * @return the random string.
532 * @throws IllegalArgumentException if {@code count} < 0.
533 * @since 3.5
534 * @deprecated Use {@link #nextGraph(int)} from {@link #secure()}, {@link #secureStrong()}, or {@link #insecure()}.
535 */
536 @Deprecated
537 public static String randomGraph(final int count) {
538 return secure().nextGraph(count);
539 }
540
541 /**
542 * Creates a random string whose length is between the inclusive minimum and the exclusive maximum.
543 *
544 * <p>
545 * Characters will be chosen from the set of \p{Graph} characters.
546 * </p>
547 *
548 * @param minLengthInclusive the inclusive minimum length of the string to generate.
549 * @param maxLengthExclusive the exclusive maximum length of the string to generate.
550 * @return the random string.
551 * @since 3.5
552 * @deprecated Use {@link #nextGraph(int, int)} from {@link #secure()}, {@link #secureStrong()}, or {@link #insecure()}.
553 */
554 @Deprecated
555 public static String randomGraph(final int minLengthInclusive, final int maxLengthExclusive) {
556 return secure().nextGraph(minLengthInclusive, maxLengthExclusive);
557 }
558
559 /**
560 * Creates a random string whose length is the number of characters specified.
561 *
562 * <p>
563 * Characters will be chosen from the set of numeric characters.
564 * </p>
565 *
566 * @param count the length of random string to create.
567 * @return the random string.
568 * @throws IllegalArgumentException if {@code count} < 0.
569 * @deprecated Use {@link #nextNumeric(int)} from {@link #secure()}, {@link #secureStrong()}, or {@link #insecure()}.
570 */
571 @Deprecated
572 public static String randomNumeric(final int count) {
573 return secure().nextNumeric(count);
574 }
575
576 /**
577 * Creates a random string whose length is between the inclusive minimum and the exclusive maximum.
578 *
579 * <p>
580 * Characters will be chosen from the set of \p{Digit} characters.
581 * </p>
582 *
583 * @param minLengthInclusive the inclusive minimum length of the string to generate.
584 * @param maxLengthExclusive the exclusive maximum length of the string to generate.
585 * @return the random string.
586 * @since 3.5
587 * @deprecated Use {@link #nextNumeric(int, int)} from {@link #secure()}, {@link #secureStrong()}, or {@link #insecure()}.
588 */
589 @Deprecated
590 public static String randomNumeric(final int minLengthInclusive, final int maxLengthExclusive) {
591 return secure().nextNumeric(minLengthInclusive, maxLengthExclusive);
592 }
593
594 /**
595 * Creates a random string whose length is the number of characters specified.
596 *
597 * <p>
598 * Characters will be chosen from the set of characters which match the POSIX [:print:] regular expression character
599 * class. This class includes all visible ASCII characters and spaces (i.e. anything except control characters).
600 * </p>
601 *
602 * @param count the length of random string to create.
603 * @return the random string.
604 * @throws IllegalArgumentException if {@code count} < 0.
605 * @since 3.5
606 * @deprecated Use {@link #nextPrint(int)} from {@link #secure()}, {@link #secureStrong()}, or {@link #insecure()}.
607 */
608 @Deprecated
609 public static String randomPrint(final int count) {
610 return secure().nextPrint(count);
611 }
612
613 /**
614 * Creates a random string whose length is between the inclusive minimum and the exclusive maximum.
615 *
616 * <p>
617 * Characters will be chosen from the set of \p{Print} characters.
618 * </p>
619 *
620 * @param minLengthInclusive the inclusive minimum length of the string to generate.
621 * @param maxLengthExclusive the exclusive maximum length of the string to generate.
622 * @return the random string.
623 * @since 3.5
624 * @deprecated Use {@link #nextPrint(int, int)} from {@link #secure()}, {@link #secureStrong()}, or {@link #insecure()}.
625 */
626 @Deprecated
627 public static String randomPrint(final int minLengthInclusive, final int maxLengthExclusive) {
628 return secure().nextPrint(minLengthInclusive, maxLengthExclusive);
629 }
630
631 /**
632 * Gets the singleton instance based on {@link SecureRandom#SecureRandom()} which uses a secure random number generator (RNG) implementing the default
633 * random number algorithm.
634 * <p>
635 * The method {@link SecureRandom#SecureRandom()} is called on-demand.
636 * </p>
637 *
638 * @return the singleton instance based on {@link SecureRandom#SecureRandom()}.
639 * @see SecureRandom#SecureRandom()
640 * @since 3.16.0
641 */
642 public static RandomStringUtils secure() {
643 return SECURE;
644 }
645
646 /**
647 * Gets the singleton instance based on {@link SecureRandom#getInstanceStrong()} which uses an algorithms/providers
648 * specified in the {@code securerandom.strongAlgorithms} {@link Security} property.
649 * <p>
650 * The method {@link SecureRandom#getInstanceStrong()} is called on-demand.
651 * </p>
652 *
653 * @return the singleton instance based on {@link SecureRandom#getInstanceStrong()}.
654 * @see SecureRandom#getInstanceStrong()
655 * @since 3.17.0
656 */
657 public static RandomStringUtils secureStrong() {
658 return SECURE_STRONG;
659 }
660
661 private final Supplier<RandomUtils> random;
662
663 /**
664 * {@link RandomStringUtils} instances should NOT be constructed in standard programming. Instead, the class should
665 * be used as {@code RandomStringUtils.random(5);}.
666 *
667 * <p>
668 * This constructor is public to permit tools that require a JavaBean instance to operate.
669 * </p>
670 *
671 * @deprecated TODO Make private in 4.0.
672 */
673 @Deprecated
674 public RandomStringUtils() {
675 this(SECURE_SUPPLIER);
676 }
677
678 private RandomStringUtils(final Supplier<RandomUtils> random) {
679 this.random = random;
680 }
681
682 /**
683 * Creates a random string whose length is the number of characters specified.
684 *
685 * <p>
686 * Characters will be chosen from the set of all characters.
687 * </p>
688 *
689 * @param count the length of random string to create.
690 * @return the random string.
691 * @throws IllegalArgumentException if {@code count} < 0.
692 * @since 3.16.0
693 */
694 public String next(final int count) {
695 return next(count, false, false);
696 }
697
698 /**
699 * Creates a random string whose length is the number of characters specified.
700 *
701 * <p>
702 * Characters will be chosen from the set of alpha-numeric characters as indicated by the arguments.
703 * </p>
704 *
705 * @param count the length of random string to create.
706 * @param letters if {@code true}, generated string may include alphabetic characters.
707 * @param numbers if {@code true}, generated string may include numeric characters.
708 * @return the random string.
709 * @throws IllegalArgumentException if {@code count} < 0.
710 * @since 3.16.0
711 */
712 public String next(final int count, final boolean letters, final boolean numbers) {
713 return next(count, 0, 0, letters, numbers);
714 }
715
716 /**
717 * Creates a random string whose length is the number of characters specified.
718 *
719 * <p>
720 * Characters will be chosen from the set of characters specified.
721 * </p>
722 *
723 * @param count the length of random string to create.
724 * @param chars the character array containing the set of characters to use, may be null.
725 * @return the random string.
726 * @throws IllegalArgumentException if {@code count} < 0.
727 * @since 3.16.0
728 */
729 public String next(final int count, final char... chars) {
730 if (chars == null) {
731 return random(count, 0, 0, false, false, null, random());
732 }
733 return random(count, 0, chars.length, false, false, chars, random());
734 }
735
736 /**
737 * Creates a random string whose length is the number of characters specified.
738 *
739 * <p>
740 * Characters will be chosen from the set of alpha-numeric characters as indicated by the arguments.
741 * </p>
742 *
743 * @param count the length of random string to create.
744 * @param start the position in set of chars to start at.
745 * @param end the position in set of chars to end before.
746 * @param letters if {@code true}, generated string may include alphabetic characters.
747 * @param numbers if {@code true}, generated string may include numeric characters.
748 * @return the random string.
749 * @throws IllegalArgumentException if {@code count} < 0.
750 * @since 3.16.0
751 */
752 public String next(final int count, final int start, final int end, final boolean letters, final boolean numbers) {
753 return random(count, start, end, letters, numbers, null, random());
754 }
755
756 /**
757 * Creates a random string based on a variety of options, using default source of randomness.
758 *
759 * <p>
760 * This method has exactly the same semantics as {@link #random(int,int,int,boolean,boolean,char[],Random)}, but
761 * instead of using an externally supplied source of randomness, it uses the internal static {@link Random}
762 * instance.
763 * </p>
764 *
765 * @param count the length of random string to create.
766 * @param start the position in set of chars to start at.
767 * @param end the position in set of chars to end before.
768 * @param letters if {@code true}, generated string may include alphabetic characters.
769 * @param numbers if {@code true}, generated string may include numeric characters.
770 * @param chars the set of chars to choose randoms from. If {@code null}, then it will use the set of all chars.
771 * @return the random string.
772 * @throws ArrayIndexOutOfBoundsException if there are not {@code (end - start) + 1} characters in the set array.
773 * @throws IllegalArgumentException if {@code count} < 0.
774 */
775 public String next(final int count, final int start, final int end, final boolean letters, final boolean numbers,
776 final char... chars) {
777 return random(count, start, end, letters, numbers, chars, random());
778 }
779
780 /**
781 * Creates a random string whose length is the number of characters specified.
782 *
783 * <p>
784 * Characters will be chosen from the set of characters specified by the string, must not be empty. If null, the set
785 * of all characters is used.
786 * </p>
787 *
788 * @param count the length of random string to create.
789 * @param chars the String containing the set of characters to use, may be null, but must not be empty.
790 * @return the random string.
791 * @throws IllegalArgumentException if {@code count} < 0 or the string is empty.
792 * @since 3.16.0
793 */
794 public String next(final int count, final String chars) {
795 if (chars == null) {
796 return random(count, 0, 0, false, false, null, random());
797 }
798 return next(count, chars.toCharArray());
799 }
800
801 /**
802 * Creates a random string whose length is the number of characters specified.
803 *
804 * <p>
805 * Characters will be chosen from the set of Latin alphabetic characters (a-z, A-Z).
806 * </p>
807 *
808 * @param count the length of random string to create.
809 * @return the random string.
810 * @throws IllegalArgumentException if {@code count} < 0.
811 */
812 public String nextAlphabetic(final int count) {
813 return next(count, true, false);
814 }
815
816 /**
817 * Creates a random string whose length is between the inclusive minimum and the exclusive maximum.
818 *
819 * <p>
820 * Characters will be chosen from the set of Latin alphabetic characters (a-z, A-Z).
821 * </p>
822 *
823 * @param minLengthInclusive the inclusive minimum length of the string to generate.
824 * @param maxLengthExclusive the exclusive maximum length of the string to generate.
825 * @return the random string.
826 * @since 3.5
827 */
828 public String nextAlphabetic(final int minLengthInclusive, final int maxLengthExclusive) {
829 return nextAlphabetic(randomUtils().randomInt(minLengthInclusive, maxLengthExclusive));
830 }
831
832 /**
833 * Creates a random string whose length is the number of characters specified.
834 *
835 * <p>
836 * Characters will be chosen from the set of Latin alphabetic characters (a-z, A-Z) and the digits 0-9.
837 * </p>
838 *
839 * @param count the length of random string to create.
840 * @return the random string.
841 * @throws IllegalArgumentException if {@code count} < 0.
842 */
843 public String nextAlphanumeric(final int count) {
844 return next(count, true, true);
845 }
846
847 /**
848 * Creates a random string whose length is between the inclusive minimum and the exclusive maximum.
849 *
850 * <p>
851 * Characters will be chosen from the set of Latin alphabetic characters (a-z, A-Z) and the digits 0-9.
852 * </p>
853 *
854 * @param minLengthInclusive the inclusive minimum length of the string to generate.
855 * @param maxLengthExclusive the exclusive maximum length of the string to generate.
856 * @return the random string.
857 * @since 3.5
858 */
859 public String nextAlphanumeric(final int minLengthInclusive, final int maxLengthExclusive) {
860 return nextAlphanumeric(randomUtils().randomInt(minLengthInclusive, maxLengthExclusive));
861 }
862
863 /**
864 * Creates a random string whose length is the number of characters specified.
865 *
866 * <p>
867 * Characters will be chosen from the set of characters whose ASCII value is between {@code 32} and {@code 126}
868 * (inclusive).
869 * </p>
870 *
871 * @param count the length of random string to create.
872 * @return the random string.
873 * @throws IllegalArgumentException if {@code count} < 0.
874 */
875 public String nextAscii(final int count) {
876 return next(count, 32, 127, false, false);
877 }
878
879 /**
880 * Creates a random string whose length is between the inclusive minimum and the exclusive maximum.
881 *
882 * <p>
883 * Characters will be chosen from the set of characters whose ASCII value is between {@code 32} and {@code 126}
884 * (inclusive).
885 * </p>
886 *
887 * @param minLengthInclusive the inclusive minimum length of the string to generate.
888 * @param maxLengthExclusive the exclusive maximum length of the string to generate.
889 * @return the random string.
890 * @since 3.5
891 */
892 public String nextAscii(final int minLengthInclusive, final int maxLengthExclusive) {
893 return nextAscii(randomUtils().randomInt(minLengthInclusive, maxLengthExclusive));
894 }
895
896 /**
897 * Creates a random string whose length is the number of characters specified.
898 *
899 * <p>
900 * Characters will be chosen from the set of characters which match the POSIX [:graph:] regular expression character
901 * class. This class contains all visible ASCII characters (i.e. anything except spaces and control characters).
902 * </p>
903 *
904 * @param count the length of random string to create.
905 * @return the random string.
906 * @throws IllegalArgumentException if {@code count} < 0.
907 * @since 3.5
908 */
909 public String nextGraph(final int count) {
910 return next(count, 33, 126, false, false);
911 }
912
913 /**
914 * Creates a random string whose length is between the inclusive minimum and the exclusive maximum.
915 *
916 * <p>
917 * Characters will be chosen from the set of \p{Graph} characters.
918 * </p>
919 *
920 * @param minLengthInclusive the inclusive minimum length of the string to generate.
921 * @param maxLengthExclusive the exclusive maximum length of the string to generate.
922 * @return the random string.
923 * @since 3.5
924 */
925 public String nextGraph(final int minLengthInclusive, final int maxLengthExclusive) {
926 return nextGraph(randomUtils().randomInt(minLengthInclusive, maxLengthExclusive));
927 }
928
929 /**
930 * Creates a random string whose length is the number of characters specified.
931 *
932 * <p>
933 * Characters will be chosen from the set of numeric characters.
934 * </p>
935 *
936 * @param count the length of random string to create.
937 * @return the random string.
938 * @throws IllegalArgumentException if {@code count} < 0.
939 */
940 public String nextNumeric(final int count) {
941 return next(count, false, true);
942 }
943
944 /**
945 * Creates a random string whose length is between the inclusive minimum and the exclusive maximum.
946 *
947 * <p>
948 * Characters will be chosen from the set of \p{Digit} characters.
949 * </p>
950 *
951 * @param minLengthInclusive the inclusive minimum length of the string to generate.
952 * @param maxLengthExclusive the exclusive maximum length of the string to generate.
953 * @return the random string.
954 * @since 3.5
955 */
956 public String nextNumeric(final int minLengthInclusive, final int maxLengthExclusive) {
957 return nextNumeric(randomUtils().randomInt(minLengthInclusive, maxLengthExclusive));
958 }
959
960 /**
961 * Creates a random string whose length is the number of characters specified.
962 *
963 * <p>
964 * Characters will be chosen from the set of characters which match the POSIX [:print:] regular expression character
965 * class. This class includes all visible ASCII characters and spaces (i.e. anything except control characters).
966 * </p>
967 *
968 * @param count the length of random string to create.
969 * @return the random string.
970 * @throws IllegalArgumentException if {@code count} < 0.
971 * @since 3.5
972 * @since 3.16.0
973 */
974 public String nextPrint(final int count) {
975 return next(count, 32, 126, false, false);
976 }
977
978 /**
979 * Creates a random string whose length is between the inclusive minimum and the exclusive maximum.
980 *
981 * <p>
982 * Characters will be chosen from the set of \p{Print} characters.
983 * </p>
984 *
985 * @param minLengthInclusive the inclusive minimum length of the string to generate.
986 * @param maxLengthExclusive the exclusive maximum length of the string to generate.
987 * @return the random string.
988 * @since 3.16.0
989 */
990 public String nextPrint(final int minLengthInclusive, final int maxLengthExclusive) {
991 return nextPrint(randomUtils().randomInt(minLengthInclusive, maxLengthExclusive));
992 }
993
994 /**
995 * Gets the Random.
996 *
997 * @return the Random.
998 */
999 private Random random() {
1000 return randomUtils().random();
1001 }
1002
1003 /**
1004 * Gets the RandomUtils.
1005 *
1006 * @return the RandomUtils.
1007 */
1008 private RandomUtils randomUtils() {
1009 return random.get();
1010 }
1011
1012 @Override
1013 public String toString() {
1014 return "RandomStringUtils [random=" + random() + "]";
1015 }
1016
1017 }