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