001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * https://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.commons.lang3; 018 019import java.security.SecureRandom; 020import java.security.Security; 021import java.util.Random; 022import java.util.concurrent.ThreadLocalRandom; 023import java.util.function.Supplier; 024 025/** 026 * Generates random {@link String}s. 027 * <p> 028 * Use {@link #secure()} to get the singleton instance based on {@link SecureRandom#SecureRandom()} which uses a secure random number generator implementing the 029 * default random number algorithm. 030 * </p> 031 * <p> 032 * Use {@link #secureStrong()} to get the singleton instance based on {@link SecureRandom#getInstanceStrong()} which uses an instance that was selected by using 033 * the algorithms/providers specified in the {@code securerandom.strongAlgorithms} {@link Security} property. 034 * </p> 035 * <p> 036 * Use {@link #insecure()} to get the singleton instance based on {@link ThreadLocalRandom#current()} <strong>which is not cryptographically secure</strong>. In addition, 037 * instances do not use a cryptographically random seed unless the {@linkplain System#getProperty system property} {@code java.util.secureRandomSeed} is set to 038 * {@code true}. 039 * </p> 040 * <p> 041 * Starting in version 3.17.0, the method {@link #secure()} uses {@link SecureRandom#SecureRandom()} instead of {@link SecureRandom#getInstanceStrong()}, and 042 * adds {@link #secureStrong()}. 043 * </p> 044 * <p> 045 * Starting in version 3.16.0, this class uses {@link #secure()} for static methods and adds {@link #insecure()}. 046 * </p> 047 * <p> 048 * Starting in version 3.15.0, this class uses {@link SecureRandom#getInstanceStrong()} for static methods. 049 * </p> 050 * <p> 051 * Before version 3.15.0, this class used {@link ThreadLocalRandom#current()} for static methods, which is not cryptographically secure. 052 * </p> 053 * <p> 054 * RandomStringUtils is intended for simple use cases. For more advanced use cases consider using Apache Commons Text's 055 * <a href= "https://commons.apache.org/proper/commons-text/javadocs/api-release/org/apache/commons/text/RandomStringGenerator.html"> RandomStringGenerator</a> 056 * instead. 057 * </p> 058 * <p> 059 * The Apache Commons project provides <a href="https://commons.apache.org/proper/commons-rng/">Commons RNG</a> dedicated to pseudo-random number generation, 060 * that may be a better choice for applications with more stringent requirements (performance and/or correctness). 061 * </p> 062 * <p> 063 * 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 064 * 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 065 * (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 066 * surrogate. 067 * </p> 068 * <p> 069 * #ThreadSafe# 070 * </p> 071 * 072 * @see #secure() 073 * @see #secureStrong() 074 * @see #insecure() 075 * @see SecureRandom#SecureRandom() 076 * @see SecureRandom#getInstanceStrong() 077 * @see ThreadLocalRandom#current() 078 * @see RandomUtils 079 * @since 1.0 080 */ 081public class RandomStringUtils { 082 083 private static final Supplier<RandomUtils> SECURE_SUPPLIER = RandomUtils::secure; 084 085 private static final RandomStringUtils INSECURE = new RandomStringUtils(RandomUtils::insecure); 086 087 private static final RandomStringUtils SECURE = new RandomStringUtils(SECURE_SUPPLIER); 088 089 private static final RandomStringUtils SECURE_STRONG = new RandomStringUtils(RandomUtils::secureStrong); 090 091 private static final char[] ALPHANUMERICAL_CHARS = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 092 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 093 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '0', '1', 094 '2', '3', '4', '5', '6', '7', '8', '9' }; 095 096 private static final int ASCII_0 = '0'; 097 private static final int ASCII_9 = '9'; 098 private static final int ASCII_A = 'A'; 099 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 Thrown 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 alphanumeric 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 Thrown 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 Thrown 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 alphanumeric 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 Thrown 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 Thrown if there are not {@code (end - start) + 1} characters in the set array. 215 * @throws IllegalArgumentException Thrown 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 Thrown if there are not {@code (end - start) + 1} characters in the set array. 252 * @throws IllegalArgumentException Thrown 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(String.format("Requested random string length %,d is less than 0.", end)); 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(String.format("Parameter end (%,d) must be greater than start (%,d)", end, start)); 277 } else if (start < 0 || end < 0) { 278 throw new IllegalArgumentException("Character positions MUST be >= 0"); 279 } else if (chars != null && start >= chars.length) { 280 throw new IllegalArgumentException("start >= chars.length"); 281 } else if (chars != null && end > chars.length) { 282 throw new IllegalArgumentException("end > chars.length"); 283 } 284 if (end > Character.MAX_CODE_POINT) { 285 // Technically, it should be `Character.MAX_CODE_POINT+1` as `end` is excluded 286 // But the character `Character.MAX_CODE_POINT` is private use, so it would anyway be excluded 287 end = Character.MAX_CODE_POINT; 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 && digits && start <= ASCII_0 && end >= ASCII_z + 1) { 297 return random(count, 0, 0, false, false, ALPHANUMERICAL_CHARS, random); 298 } 299 // Only reject when none of the requested categories is reachable; otherwise a letters && digits 300 // request would throw on a range that holds one category but not the other (e.g. [ASCII_0, ASCII_A)). 301 if ((!digits || end <= ASCII_0) && (!letters || end <= ASCII_A) && (digits || letters)) { 302 throw new IllegalArgumentException( 303 String.format("Parameter end (%,d) must be greater than (%,d) for generating digits or greater than (%,d) for generating letters.", end, 304 ASCII_0, ASCII_A)); 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 && digits) { 315 start = Math.max(ASCII_0, start); 316 end = Math.min(ASCII_z + 1, end); 317 // The clamp can empty the range when it sits above the alphanumerics (e.g. [ASCII_z + 1, 0x7f)), 318 // unlike the single-category branches below which are validated by the reachability loops further 319 // down. Reject here so the caller gets a clear range error instead of nextBits(0) failing later. 320 if (start >= end) { 321 throw new IllegalArgumentException(String.format("No letters or digits exist between start %,d and end %,d.", start, end)); 322 } 323 } else if (digits) { 324 // just numbers, no letters 325 start = Math.max(ASCII_0, start); 326 end = Math.min(ASCII_9 + 1, end); 327 } else if (letters) { 328 // just letters, no numbers 329 start = Math.max(ASCII_A, start); 330 end = Math.min(ASCII_z + 1, end); 331 } 332 } 333 if (chars == null) { 334 // start/end are code points: validate using Character.isLetter/isDigit on the 335 // code-point range rather than on the loop index. 336 if (letters && !digits) { 337 boolean ok = false; 338 for (int i = start; i < end; i++) { 339 if (Character.isLetter(i)) { 340 ok = true; 341 break; 342 } 343 } 344 if (!ok) { 345 throw new IllegalArgumentException(String.format("No letters exist between start %,d and end %,d.", start, end)); 346 } 347 } 348 if (!letters && digits) { 349 boolean ok = false; 350 for (int i = start; i < end; i++) { 351 if (Character.isDigit(i)) { 352 ok = true; 353 break; 354 } 355 } 356 if (!ok) { 357 throw new IllegalArgumentException(String.format("No digits exist between start %,d and end %,d.", start, end)); 358 } 359 } 360 } else if (letters || digits) { 361 // chars != null. start/end are indices into chars[]; validate the actual 362 // chars contain at least one element matching some requested letter/digit 363 // category to avoid an infinite generation loop when the array lacks every 364 // requested category. 365 boolean hasMatch = false; 366 for (int i = start; i < end; i++) { 367 final char c = chars[i]; 368 if (letters && Character.isLetter(c) || digits && Character.isDigit(c)) { 369 hasMatch = true; 370 break; 371 } 372 } 373 if (!hasMatch) { 374 throw new IllegalArgumentException(String.format("No %s%s%s exist in chars[%,d..%,d).", letters ? "letters" : "", 375 letters && digits ? " or " : "", digits ? "digits" : "", start, end)); 376 } 377 } 378 final StringBuilder builder = new StringBuilder(count); 379 final int gap = end - start; 380 final int gapBits = Integer.SIZE - Integer.numberOfLeadingZeros(gap); 381 // The size of the cache we use is an heuristic: 382 // about twice the number of bytes required if no rejection 383 // Ideally the cache size depends on multiple factor, including the cost of generating x bytes 384 // of randomness as well as the probability of rejection. It is however not easy to know 385 // those values programmatically for the general case. 386 // Calculate cache size: 387 // 1. Multiply count by bits needed per character (gapBits) 388 // 2. Add padding bits (3) to handle partial bytes 389 // 3. Divide by 5 to convert to bytes (normally this would be by 8, dividing by 5 allows for about 60% extra space) 390 // 4. Add base padding (10) to handle small counts efficiently 391 // 5. Ensure we don't exceed Integer.MAX_VALUE / 5 + 10 to provide a good balance between overflow prevention and 392 // making the cache extremely large 393 final long desiredCacheSize = ((long) count * gapBits + CACHE_PADDING_BITS) / BITS_TO_BYTES_DIVISOR + BASE_CACHE_SIZE_PADDING; 394 final int cacheSize = (int) Math.min(desiredCacheSize, Integer.MAX_VALUE / BITS_TO_BYTES_DIVISOR + BASE_CACHE_SIZE_PADDING); 395 final CachedRandomBits arb = new CachedRandomBits(cacheSize, random); 396 // Bound consecutive rejected draws so impossible requests eventually fail. 397 // Assuming independent uniform draws and at least one value acceptable for 398 // the remaining output length, the acceptance probability is at least 399 // 1 / 2^gapBits. A budget of 64 times that sample space makes the probability 400 // of exhausting the budget less than exp(-64) per accepted code point. 401 // Reset the counter after each accepted code point. 402 final long maxRejections = 64L << gapBits; 403 long rejections = 0; 404 while (count-- != 0) { 405 // Generate a random value between start (included) and end (excluded) 406 final int randomValue = arb.nextBits(gapBits) + start; 407 // Rejection sampling if value too large 408 if (randomValue >= end) { 409 count++; 410 if (++rejections > maxRejections) { 411 throw new IllegalArgumentException( 412 String.format("No acceptable code points found in range [%,d, %,d) within %,d attempts.", start, end, maxRejections)); 413 } 414 continue; 415 } 416 final int codePoint; 417 if (chars == null) { 418 codePoint = randomValue; 419 switch (Character.getType(codePoint)) { 420 case Character.UNASSIGNED: 421 case Character.PRIVATE_USE: 422 case Character.SURROGATE: 423 count++; 424 if (++rejections > maxRejections) { 425 throw new IllegalArgumentException( 426 String.format("No acceptable code points found in range [%,d, %,d) within %,d attempts.", start, end, maxRejections)); 427 } 428 continue; 429 } 430 } else { 431 codePoint = chars[randomValue]; 432 } 433 final int numberOfChars = Character.charCount(codePoint); 434 if (count == 0 && numberOfChars > 1) { 435 count++; 436 if (++rejections > maxRejections) { 437 throw new IllegalArgumentException( 438 String.format("No acceptable code points found in range [%,d, %,d) within %,d attempts.", start, end, maxRejections)); 439 } 440 continue; 441 } 442 if (letters && Character.isLetter(codePoint) || digits && Character.isDigit(codePoint) || !letters && !digits) { 443 builder.appendCodePoint(codePoint); 444 if (numberOfChars == 2) { 445 count--; 446 } 447 rejections = 0; 448 } else { 449 count++; 450 if (++rejections > maxRejections) { 451 throw new IllegalArgumentException( 452 String.format("No acceptable code points found in range [%,d, %,d) within %,d attempts.", start, end, maxRejections)); 453 } 454 } 455 } 456 return builder.toString(); 457 } 458 459 /** 460 * Creates a random string whose length is the number of characters specified. 461 * 462 * <p> 463 * Characters will be chosen from the set of characters specified by the string, must not be empty. If null, the set 464 * of all characters is used. 465 * </p> 466 * 467 * @param count The length of random string to create. 468 * @param chars The String containing the set of characters to use, may be null, but must not be empty. 469 * @return The random string. 470 * @throws IllegalArgumentException Thrown if {@code count} < 0 or the string is empty. 471 * @deprecated Use {@link #next(int, String)} from {@link #secure()}, {@link #secureStrong()}, or {@link #insecure()}. 472 */ 473 @Deprecated 474 public static String random(final int count, final String chars) { 475 return secure().next(count, chars); 476 } 477 478 /** 479 * Creates a random string whose length is the number of characters specified. 480 * 481 * <p> 482 * Characters will be chosen from the set of Latin alphabetic characters (a-z, A-Z). 483 * </p> 484 * 485 * @param count The length of random string to create. 486 * @return The random string. 487 * @throws IllegalArgumentException Thrown if {@code count} < 0. 488 * @deprecated Use {@link #nextAlphabetic(int)} from {@link #secure()}, {@link #secureStrong()}, or {@link #insecure()}. 489 */ 490 @Deprecated 491 public static String randomAlphabetic(final int count) { 492 return secure().nextAlphabetic(count); 493 } 494 495 /** 496 * Creates a random string whose length is between the inclusive minimum and the exclusive maximum. 497 * 498 * <p> 499 * Characters will be chosen from the set of Latin alphabetic characters (a-z, A-Z). 500 * </p> 501 * 502 * @param minLengthInclusive The inclusive minimum length of the string to generate. 503 * @param maxLengthExclusive The exclusive maximum length of the string to generate. 504 * @return The random string. 505 * @since 3.5 506 * @deprecated Use {@link #nextAlphabetic(int, int)} from {@link #secure()}, {@link #secureStrong()}, or {@link #insecure()}. 507 */ 508 @Deprecated 509 public static String randomAlphabetic(final int minLengthInclusive, final int maxLengthExclusive) { 510 return secure().nextAlphabetic(minLengthInclusive, maxLengthExclusive); 511 } 512 513 /** 514 * Creates a random string whose length is the number of characters specified. 515 * 516 * <p> 517 * Characters will be chosen from the set of Latin alphabetic characters (a-z, A-Z) and the digits 0-9. 518 * </p> 519 * 520 * @param count The length of random string to create. 521 * @return The random string. 522 * @throws IllegalArgumentException Thrown if {@code count} < 0. 523 * @deprecated Use {@link #nextAlphanumeric(int)} from {@link #secure()}, {@link #secureStrong()}, or {@link #insecure()}. 524 */ 525 @Deprecated 526 public static String randomAlphanumeric(final int count) { 527 return secure().nextAlphanumeric(count); 528 } 529 530 /** 531 * Creates a random string whose length is between the inclusive minimum and the exclusive maximum. 532 * 533 * <p> 534 * Characters will be chosen from the set of Latin alphabetic characters (a-z, A-Z) and the digits 0-9. 535 * </p> 536 * 537 * @param minLengthInclusive The inclusive minimum length of the string to generate. 538 * @param maxLengthExclusive The exclusive maximum length of the string to generate. 539 * @return The random string. 540 * @since 3.5 541 * @deprecated Use {@link #nextAlphanumeric(int, int)} from {@link #secure()}, {@link #secureStrong()}, or {@link #insecure()}. 542 */ 543 @Deprecated 544 public static String randomAlphanumeric(final int minLengthInclusive, final int maxLengthExclusive) { 545 return secure().nextAlphanumeric(minLengthInclusive, maxLengthExclusive); 546 } 547 548 /** 549 * Creates a random string whose length is the number of characters specified. 550 * 551 * <p> 552 * Characters will be chosen from the set of characters whose ASCII value is between {@code 32} and {@code 126} 553 * (inclusive). 554 * </p> 555 * 556 * @param count The length of random string to create. 557 * @return The random string. 558 * @throws IllegalArgumentException Thrown if {@code count} < 0. 559 * @deprecated Use {@link #nextAscii(int)} from {@link #secure()}, {@link #secureStrong()}, or {@link #insecure()}. 560 */ 561 @Deprecated 562 public static String randomAscii(final int count) { 563 return secure().nextAscii(count); 564 } 565 566 /** 567 * Creates a random string whose length is between the inclusive minimum and the exclusive maximum. 568 * 569 * <p> 570 * Characters will be chosen from the set of characters whose ASCII value is between {@code 32} and {@code 126} 571 * (inclusive). 572 * </p> 573 * 574 * @param minLengthInclusive The inclusive minimum length of the string to generate. 575 * @param maxLengthExclusive The exclusive maximum length of the string to generate. 576 * @return The random string. 577 * @since 3.5 578 * @deprecated Use {@link #nextAscii(int, int)} from {@link #secure()}, {@link #secureStrong()}, or {@link #insecure()}. 579 */ 580 @Deprecated 581 public static String randomAscii(final int minLengthInclusive, final int maxLengthExclusive) { 582 return secure().nextAscii(minLengthInclusive, maxLengthExclusive); 583 } 584 585 /** 586 * Creates a random string whose length is the number of characters specified. 587 * 588 * <p> 589 * Characters will be chosen from the set of characters which match the POSIX [:graph:] regular expression character 590 * class. This class contains all visible ASCII characters (i.e. anything except spaces and control characters). 591 * </p> 592 * 593 * @param count The length of random string to create. 594 * @return The random string. 595 * @throws IllegalArgumentException Thrown if {@code count} < 0. 596 * @since 3.5 597 * @deprecated Use {@link #nextGraph(int)} from {@link #secure()}, {@link #secureStrong()}, or {@link #insecure()}. 598 */ 599 @Deprecated 600 public static String randomGraph(final int count) { 601 return secure().nextGraph(count); 602 } 603 604 /** 605 * Creates a random string whose length is between the inclusive minimum and the exclusive maximum. 606 * 607 * <p> 608 * Characters will be chosen from the set of \p{Graph} characters. 609 * </p> 610 * 611 * @param minLengthInclusive The inclusive minimum length of the string to generate. 612 * @param maxLengthExclusive The exclusive maximum length of the string to generate. 613 * @return The random string. 614 * @since 3.5 615 * @deprecated Use {@link #nextGraph(int, int)} from {@link #secure()}, {@link #secureStrong()}, or {@link #insecure()}. 616 */ 617 @Deprecated 618 public static String randomGraph(final int minLengthInclusive, final int maxLengthExclusive) { 619 return secure().nextGraph(minLengthInclusive, maxLengthExclusive); 620 } 621 622 /** 623 * Creates a random string whose length is the number of characters specified. 624 * 625 * <p> 626 * Characters will be chosen from the set of numeric characters. 627 * </p> 628 * 629 * @param count The length of random string to create. 630 * @return The random string. 631 * @throws IllegalArgumentException Thrown if {@code count} < 0. 632 * @deprecated Use {@link #nextNumeric(int)} from {@link #secure()}, {@link #secureStrong()}, or {@link #insecure()}. 633 */ 634 @Deprecated 635 public static String randomNumeric(final int count) { 636 return secure().nextNumeric(count); 637 } 638 639 /** 640 * Creates a random string whose length is between the inclusive minimum and the exclusive maximum. 641 * 642 * <p> 643 * Characters will be chosen from the set of \p{Digit} characters. 644 * </p> 645 * 646 * @param minLengthInclusive The inclusive minimum length of the string to generate. 647 * @param maxLengthExclusive The exclusive maximum length of the string to generate. 648 * @return The random string. 649 * @since 3.5 650 * @deprecated Use {@link #nextNumeric(int, int)} from {@link #secure()}, {@link #secureStrong()}, or {@link #insecure()}. 651 */ 652 @Deprecated 653 public static String randomNumeric(final int minLengthInclusive, final int maxLengthExclusive) { 654 return secure().nextNumeric(minLengthInclusive, maxLengthExclusive); 655 } 656 657 /** 658 * Creates a random string whose length is the number of characters specified. 659 * 660 * <p> 661 * Characters will be chosen from the set of characters which match the POSIX [:print:] regular expression character 662 * class. This class includes all visible ASCII characters and spaces (i.e. anything except control characters). 663 * </p> 664 * 665 * @param count The length of random string to create. 666 * @return The random string. 667 * @throws IllegalArgumentException Thrown if {@code count} < 0. 668 * @since 3.5 669 * @deprecated Use {@link #nextPrint(int)} from {@link #secure()}, {@link #secureStrong()}, or {@link #insecure()}. 670 */ 671 @Deprecated 672 public static String randomPrint(final int count) { 673 return secure().nextPrint(count); 674 } 675 676 /** 677 * Creates a random string whose length is between the inclusive minimum and the exclusive maximum. 678 * 679 * <p> 680 * Characters will be chosen from the set of \p{Print} characters. 681 * </p> 682 * 683 * @param minLengthInclusive The inclusive minimum length of the string to generate. 684 * @param maxLengthExclusive The exclusive maximum length of the string to generate. 685 * @return The random string. 686 * @since 3.5 687 * @deprecated Use {@link #nextPrint(int, int)} from {@link #secure()}, {@link #secureStrong()}, or {@link #insecure()}. 688 */ 689 @Deprecated 690 public static String randomPrint(final int minLengthInclusive, final int maxLengthExclusive) { 691 return secure().nextPrint(minLengthInclusive, maxLengthExclusive); 692 } 693 694 /** 695 * Gets the singleton instance based on {@link SecureRandom#SecureRandom()} which uses a secure random number generator (RNG) implementing the default 696 * random number algorithm. 697 * <p> 698 * The method {@link SecureRandom#SecureRandom()} is called on-demand. 699 * </p> 700 * 701 * @return The singleton instance based on {@link SecureRandom#SecureRandom()}. 702 * @see SecureRandom#SecureRandom() 703 * @since 3.16.0 704 */ 705 public static RandomStringUtils secure() { 706 return SECURE; 707 } 708 709 /** 710 * Gets the singleton instance based on {@link SecureRandom#getInstanceStrong()} which uses an algorithms/providers 711 * specified in the {@code securerandom.strongAlgorithms} {@link Security} property. 712 * <p> 713 * The method {@link SecureRandom#getInstanceStrong()} is called on-demand. 714 * </p> 715 * 716 * @return The singleton instance based on {@link SecureRandom#getInstanceStrong()}. 717 * @see SecureRandom#getInstanceStrong() 718 * @since 3.17.0 719 */ 720 public static RandomStringUtils secureStrong() { 721 return SECURE_STRONG; 722 } 723 724 private final Supplier<RandomUtils> random; 725 726 /** 727 * {@link RandomStringUtils} instances should NOT be constructed in standard programming. Instead, the class should 728 * be used as {@code RandomStringUtils.random(5);}. 729 * 730 * <p> 731 * This constructor is public to permit tools that require a JavaBean instance to operate. 732 * </p> 733 * 734 * @deprecated TODO Make private in 4.0. 735 */ 736 @Deprecated 737 public RandomStringUtils() { 738 this(SECURE_SUPPLIER); 739 } 740 741 private RandomStringUtils(final Supplier<RandomUtils> random) { 742 this.random = random; 743 } 744 745 /** 746 * Creates a random string whose length is the number of characters specified. 747 * 748 * <p> 749 * Characters will be chosen from the set of all characters. 750 * </p> 751 * 752 * @param count The length of random string to create. 753 * @return The random string. 754 * @throws IllegalArgumentException Thrown if {@code count} < 0. 755 * @since 3.16.0 756 */ 757 public String next(final int count) { 758 return next(count, false, false); 759 } 760 761 /** 762 * Creates a random string whose length is the number of characters specified. 763 * 764 * <p> 765 * Characters will be chosen from the set of alphanumeric characters as indicated by the arguments. 766 * </p> 767 * 768 * @param count The length of random string to create. 769 * @param letters if {@code true}, generated string may include alphabetic characters. 770 * @param numbers if {@code true}, generated string may include numeric characters. 771 * @return The random string. 772 * @throws IllegalArgumentException Thrown if {@code count} < 0. 773 * @since 3.16.0 774 */ 775 public String next(final int count, final boolean letters, final boolean numbers) { 776 return next(count, 0, 0, letters, numbers); 777 } 778 779 /** 780 * Creates a random string whose length is the number of characters specified. 781 * 782 * <p> 783 * Characters will be chosen from the set of characters specified. 784 * </p> 785 * 786 * @param count The length of random string to create. 787 * @param chars The character array containing the set of characters to use, may be null. 788 * @return The random string. 789 * @throws IllegalArgumentException Thrown if {@code count} < 0. 790 * @since 3.16.0 791 */ 792 public String next(final int count, final char... chars) { 793 if (chars == null) { 794 return random(count, 0, 0, false, false, null, random()); 795 } 796 return random(count, 0, chars.length, false, false, chars, random()); 797 } 798 799 /** 800 * Creates a random string whose length is the number of characters specified. 801 * 802 * <p> 803 * Characters will be chosen from the set of alphanumeric characters as indicated by the arguments. 804 * </p> 805 * 806 * @param count The length of random string to create. 807 * @param start The position in set of chars to start at. 808 * @param end The position in set of chars to end before. 809 * @param letters if {@code true}, generated string may include alphabetic characters. 810 * @param numbers if {@code true}, generated string may include numeric characters. 811 * @return The random string. 812 * @throws IllegalArgumentException Thrown if {@code count} < 0. 813 * @since 3.16.0 814 */ 815 public String next(final int count, final int start, final int end, final boolean letters, final boolean numbers) { 816 return random(count, start, end, letters, numbers, null, random()); 817 } 818 819 /** 820 * Creates a random string based on a variety of options, using default source of randomness. 821 * 822 * <p> 823 * This method has exactly the same semantics as {@link #random(int,int,int,boolean,boolean,char[],Random)}, but 824 * instead of using an externally supplied source of randomness, it uses the internal static {@link Random} 825 * instance. 826 * </p> 827 * 828 * @param count The length of random string to create. 829 * @param start The position in set of chars to start at. 830 * @param end The position in set of chars to end before. 831 * @param letters if {@code true}, generated string may include alphabetic characters. 832 * @param numbers if {@code true}, generated string may include numeric characters. 833 * @param chars The set of chars to choose randoms from. If {@code null}, then it will use the set of all chars. 834 * @return The random string. 835 * @throws ArrayIndexOutOfBoundsException Thrown if there are not {@code (end - start) + 1} characters in the set array. 836 * @throws IllegalArgumentException Thrown if {@code count} < 0. 837 */ 838 public String next(final int count, final int start, final int end, final boolean letters, final boolean numbers, 839 final char... chars) { 840 return random(count, start, end, letters, numbers, chars, random()); 841 } 842 843 /** 844 * Creates a random string whose length is the number of characters specified. 845 * 846 * <p> 847 * Characters will be chosen from the set of characters specified by the string, must not be empty. If null, the set 848 * of all characters is used. 849 * </p> 850 * 851 * @param count The length of random string to create. 852 * @param chars The String containing the set of characters to use, may be null, but must not be empty. 853 * @return The random string. 854 * @throws IllegalArgumentException Thrown if {@code count} < 0 or the string is empty. 855 * @since 3.16.0 856 */ 857 public String next(final int count, final String chars) { 858 if (chars == null) { 859 return random(count, 0, 0, false, false, null, random()); 860 } 861 return next(count, chars.toCharArray()); 862 } 863 864 /** 865 * Creates a random string whose length is the number of characters specified. 866 * 867 * <p> 868 * Characters will be chosen from the set of Latin alphabetic characters (a-z, A-Z). 869 * </p> 870 * 871 * @param count The length of random string to create. 872 * @return The random string. 873 * @throws IllegalArgumentException Thrown if {@code count} < 0. 874 */ 875 public String nextAlphabetic(final int count) { 876 return next(count, true, 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 Latin alphabetic characters (a-z, A-Z). 884 * </p> 885 * 886 * @param minLengthInclusive The inclusive minimum length of the string to generate. 887 * @param maxLengthExclusive The exclusive maximum length of the string to generate. 888 * @return The random string. 889 * @since 3.5 890 */ 891 public String nextAlphabetic(final int minLengthInclusive, final int maxLengthExclusive) { 892 return nextAlphabetic(randomUtils().randomInt(minLengthInclusive, maxLengthExclusive)); 893 } 894 895 /** 896 * Creates a random string whose length is the number of characters specified. 897 * 898 * <p> 899 * Characters will be chosen from the set of Latin alphabetic characters (a-z, A-Z) and the digits 0-9. 900 * </p> 901 * 902 * @param count The length of random string to create. 903 * @return The random string. 904 * @throws IllegalArgumentException Thrown if {@code count} < 0. 905 */ 906 public String nextAlphanumeric(final int count) { 907 return next(count, true, true); 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 Latin alphabetic characters (a-z, A-Z) and the digits 0-9. 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 nextAlphanumeric(final int minLengthInclusive, final int maxLengthExclusive) { 923 return nextAlphanumeric(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 characters whose ASCII value is between {@code 32} and {@code 126} 931 * (inclusive). 932 * </p> 933 * 934 * @param count The length of random string to create. 935 * @return The random string. 936 * @throws IllegalArgumentException Thrown if {@code count} < 0. 937 */ 938 public String nextAscii(final int count) { 939 return next(count, 32, 127, false, false); 940 } 941 942 /** 943 * Creates a random string whose length is between the inclusive minimum and the exclusive maximum. 944 * 945 * <p> 946 * Characters will be chosen from the set of characters whose ASCII value is between {@code 32} and {@code 126} 947 * (inclusive). 948 * </p> 949 * 950 * @param minLengthInclusive The inclusive minimum length of the string to generate. 951 * @param maxLengthExclusive The exclusive maximum length of the string to generate. 952 * @return The random string. 953 * @since 3.5 954 */ 955 public String nextAscii(final int minLengthInclusive, final int maxLengthExclusive) { 956 return nextAscii(randomUtils().randomInt(minLengthInclusive, maxLengthExclusive)); 957 } 958 959 /** 960 * Creates a random string whose length is the number of characters specified. 961 * 962 * <p> 963 * Characters will be chosen from the set of characters which match the POSIX [:graph:] regular expression character 964 * class. This class contains all visible ASCII characters (i.e. anything except spaces and control characters). 965 * </p> 966 * 967 * @param count The length of random string to create. 968 * @return The random string. 969 * @throws IllegalArgumentException Thrown if {@code count} < 0. 970 * @since 3.5 971 */ 972 public String nextGraph(final int count) { 973 return next(count, 33, 127, false, false); 974 } 975 976 /** 977 * Creates a random string whose length is between the inclusive minimum and the exclusive maximum. 978 * 979 * <p> 980 * Characters will be chosen from the set of \p{Graph} characters. 981 * </p> 982 * 983 * @param minLengthInclusive The inclusive minimum length of the string to generate. 984 * @param maxLengthExclusive The exclusive maximum length of the string to generate. 985 * @return The random string. 986 * @since 3.5 987 */ 988 public String nextGraph(final int minLengthInclusive, final int maxLengthExclusive) { 989 return nextGraph(randomUtils().randomInt(minLengthInclusive, maxLengthExclusive)); 990 } 991 992 /** 993 * Creates a random string whose length is the number of characters specified. 994 * 995 * <p> 996 * Characters will be chosen from the set of numeric characters. 997 * </p> 998 * 999 * @param count The length of random string to create. 1000 * @return The random string. 1001 * @throws IllegalArgumentException Thrown if {@code count} < 0. 1002 */ 1003 public String nextNumeric(final int count) { 1004 return next(count, false, true); 1005 } 1006 1007 /** 1008 * Creates a random string whose length is between the inclusive minimum and the exclusive maximum. 1009 * 1010 * <p> 1011 * Characters will be chosen from the set of \p{Digit} characters. 1012 * </p> 1013 * 1014 * @param minLengthInclusive The inclusive minimum length of the string to generate. 1015 * @param maxLengthExclusive The exclusive maximum length of the string to generate. 1016 * @return The random string. 1017 * @since 3.5 1018 */ 1019 public String nextNumeric(final int minLengthInclusive, final int maxLengthExclusive) { 1020 return nextNumeric(randomUtils().randomInt(minLengthInclusive, maxLengthExclusive)); 1021 } 1022 1023 /** 1024 * Creates a random string whose length is the number of characters specified. 1025 * 1026 * <p> 1027 * Characters will be chosen from the set of characters which match the POSIX [:print:] regular expression character 1028 * class. This class includes all visible ASCII characters and spaces (i.e. anything except control characters). 1029 * </p> 1030 * 1031 * @param count The length of random string to create. 1032 * @return The random string. 1033 * @throws IllegalArgumentException Thrown if {@code count} < 0. 1034 * @since 3.5 1035 * @since 3.16.0 1036 */ 1037 public String nextPrint(final int count) { 1038 return next(count, 32, 127, false, false); 1039 } 1040 1041 /** 1042 * Creates a random string whose length is between the inclusive minimum and the exclusive maximum. 1043 * 1044 * <p> 1045 * Characters will be chosen from the set of \p{Print} characters. 1046 * </p> 1047 * 1048 * @param minLengthInclusive The inclusive minimum length of the string to generate. 1049 * @param maxLengthExclusive The exclusive maximum length of the string to generate. 1050 * @return The random string. 1051 * @since 3.16.0 1052 */ 1053 public String nextPrint(final int minLengthInclusive, final int maxLengthExclusive) { 1054 return nextPrint(randomUtils().randomInt(minLengthInclusive, maxLengthExclusive)); 1055 } 1056 1057 /** 1058 * Gets the Random. 1059 * 1060 * @return The Random. 1061 */ 1062 private Random random() { 1063 return randomUtils().random(); 1064 } 1065 1066 /** 1067 * Gets the RandomUtils. 1068 * 1069 * @return The RandomUtils. 1070 */ 1071 private RandomUtils randomUtils() { 1072 return random.get(); 1073 } 1074 1075 @Override 1076 public String toString() { 1077 return "RandomStringUtils [random=" + random() + "]"; 1078 } 1079 1080}