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 }