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 rejection retries so a range that rejects every sample 397 // (for example, entirely UNASSIGNED/PRIVATE_USE/SURROGATE) raises an 398 // IllegalArgumentException instead of looping indefinitely. Cap is 399 // (end - start) * 10 with a small floor so tiny gaps still get a 400 // reasonable budget. The counter resets on every accepted code point. 401 final int maxRejections = Math.max(64, gap * 10); 402 int rejections = 0; 403 while (count-- != 0) { 404 // Generate a random value between start (included) and end (excluded) 405 final int randomValue = arb.nextBits(gapBits) + start; 406 // Rejection sampling if value too large 407 if (randomValue >= end) { 408 count++; 409 if (++rejections > maxRejections) { 410 throw new IllegalArgumentException( 411 String.format("No acceptable code points found in range [%,d, %,d) within %,d attempts.", start, end, maxRejections)); 412 } 413 continue; 414 } 415 final int codePoint; 416 if (chars == null) { 417 codePoint = randomValue; 418 switch (Character.getType(codePoint)) { 419 case Character.UNASSIGNED: 420 case Character.PRIVATE_USE: 421 case Character.SURROGATE: 422 count++; 423 if (++rejections > maxRejections) { 424 throw new IllegalArgumentException( 425 String.format("No acceptable code points found in range [%,d, %,d) within %,d attempts.", start, end, maxRejections)); 426 } 427 continue; 428 } 429 } else { 430 codePoint = chars[randomValue]; 431 } 432 final int numberOfChars = Character.charCount(codePoint); 433 if (count == 0 && numberOfChars > 1) { 434 count++; 435 if (++rejections > maxRejections) { 436 throw new IllegalArgumentException( 437 String.format("No acceptable code points found in range [%,d, %,d) within %,d attempts.", start, end, maxRejections)); 438 } 439 continue; 440 } 441 if (letters && Character.isLetter(codePoint) || digits && Character.isDigit(codePoint) || !letters && !digits) { 442 builder.appendCodePoint(codePoint); 443 if (numberOfChars == 2) { 444 count--; 445 } 446 rejections = 0; 447 } else { 448 count++; 449 if (++rejections > maxRejections) { 450 throw new IllegalArgumentException( 451 String.format("No acceptable code points found in range [%,d, %,d) within %,d attempts.", start, end, maxRejections)); 452 } 453 } 454 } 455 return builder.toString(); 456 } 457 458 /** 459 * Creates a random string whose length is the number of characters specified. 460 * 461 * <p> 462 * Characters will be chosen from the set of characters specified by the string, must not be empty. If null, the set 463 * of all characters is used. 464 * </p> 465 * 466 * @param count The length of random string to create. 467 * @param chars The String containing the set of characters to use, may be null, but must not be empty. 468 * @return The random string. 469 * @throws IllegalArgumentException Thrown if {@code count} < 0 or the string is empty. 470 * @deprecated Use {@link #next(int, String)} from {@link #secure()}, {@link #secureStrong()}, or {@link #insecure()}. 471 */ 472 @Deprecated 473 public static String random(final int count, final String chars) { 474 return secure().next(count, chars); 475 } 476 477 /** 478 * Creates a random string whose length is the number of characters specified. 479 * 480 * <p> 481 * Characters will be chosen from the set of Latin alphabetic characters (a-z, A-Z). 482 * </p> 483 * 484 * @param count The length of random string to create. 485 * @return The random string. 486 * @throws IllegalArgumentException Thrown if {@code count} < 0. 487 * @deprecated Use {@link #nextAlphabetic(int)} from {@link #secure()}, {@link #secureStrong()}, or {@link #insecure()}. 488 */ 489 @Deprecated 490 public static String randomAlphabetic(final int count) { 491 return secure().nextAlphabetic(count); 492 } 493 494 /** 495 * Creates a random string whose length is between the inclusive minimum and the exclusive maximum. 496 * 497 * <p> 498 * Characters will be chosen from the set of Latin alphabetic characters (a-z, A-Z). 499 * </p> 500 * 501 * @param minLengthInclusive The inclusive minimum length of the string to generate. 502 * @param maxLengthExclusive The exclusive maximum length of the string to generate. 503 * @return The random string. 504 * @since 3.5 505 * @deprecated Use {@link #nextAlphabetic(int, int)} from {@link #secure()}, {@link #secureStrong()}, or {@link #insecure()}. 506 */ 507 @Deprecated 508 public static String randomAlphabetic(final int minLengthInclusive, final int maxLengthExclusive) { 509 return secure().nextAlphabetic(minLengthInclusive, maxLengthExclusive); 510 } 511 512 /** 513 * Creates a random string whose length is the number of characters specified. 514 * 515 * <p> 516 * Characters will be chosen from the set of Latin alphabetic characters (a-z, A-Z) and the digits 0-9. 517 * </p> 518 * 519 * @param count The length of random string to create. 520 * @return The random string. 521 * @throws IllegalArgumentException Thrown if {@code count} < 0. 522 * @deprecated Use {@link #nextAlphanumeric(int)} from {@link #secure()}, {@link #secureStrong()}, or {@link #insecure()}. 523 */ 524 @Deprecated 525 public static String randomAlphanumeric(final int count) { 526 return secure().nextAlphanumeric(count); 527 } 528 529 /** 530 * Creates a random string whose length is between the inclusive minimum and the exclusive maximum. 531 * 532 * <p> 533 * Characters will be chosen from the set of Latin alphabetic characters (a-z, A-Z) and the digits 0-9. 534 * </p> 535 * 536 * @param minLengthInclusive The inclusive minimum length of the string to generate. 537 * @param maxLengthExclusive The exclusive maximum length of the string to generate. 538 * @return The random string. 539 * @since 3.5 540 * @deprecated Use {@link #nextAlphanumeric(int, int)} from {@link #secure()}, {@link #secureStrong()}, or {@link #insecure()}. 541 */ 542 @Deprecated 543 public static String randomAlphanumeric(final int minLengthInclusive, final int maxLengthExclusive) { 544 return secure().nextAlphanumeric(minLengthInclusive, maxLengthExclusive); 545 } 546 547 /** 548 * Creates a random string whose length is the number of characters specified. 549 * 550 * <p> 551 * Characters will be chosen from the set of characters whose ASCII value is between {@code 32} and {@code 126} 552 * (inclusive). 553 * </p> 554 * 555 * @param count The length of random string to create. 556 * @return The random string. 557 * @throws IllegalArgumentException Thrown if {@code count} < 0. 558 * @deprecated Use {@link #nextAscii(int)} from {@link #secure()}, {@link #secureStrong()}, or {@link #insecure()}. 559 */ 560 @Deprecated 561 public static String randomAscii(final int count) { 562 return secure().nextAscii(count); 563 } 564 565 /** 566 * Creates a random string whose length is between the inclusive minimum and the exclusive maximum. 567 * 568 * <p> 569 * Characters will be chosen from the set of characters whose ASCII value is between {@code 32} and {@code 126} 570 * (inclusive). 571 * </p> 572 * 573 * @param minLengthInclusive The inclusive minimum length of the string to generate. 574 * @param maxLengthExclusive The exclusive maximum length of the string to generate. 575 * @return The random string. 576 * @since 3.5 577 * @deprecated Use {@link #nextAscii(int, int)} from {@link #secure()}, {@link #secureStrong()}, or {@link #insecure()}. 578 */ 579 @Deprecated 580 public static String randomAscii(final int minLengthInclusive, final int maxLengthExclusive) { 581 return secure().nextAscii(minLengthInclusive, maxLengthExclusive); 582 } 583 584 /** 585 * Creates a random string whose length is the number of characters specified. 586 * 587 * <p> 588 * Characters will be chosen from the set of characters which match the POSIX [:graph:] regular expression character 589 * class. This class contains all visible ASCII characters (i.e. anything except spaces and control characters). 590 * </p> 591 * 592 * @param count The length of random string to create. 593 * @return The random string. 594 * @throws IllegalArgumentException Thrown if {@code count} < 0. 595 * @since 3.5 596 * @deprecated Use {@link #nextGraph(int)} from {@link #secure()}, {@link #secureStrong()}, or {@link #insecure()}. 597 */ 598 @Deprecated 599 public static String randomGraph(final int count) { 600 return secure().nextGraph(count); 601 } 602 603 /** 604 * Creates a random string whose length is between the inclusive minimum and the exclusive maximum. 605 * 606 * <p> 607 * Characters will be chosen from the set of \p{Graph} characters. 608 * </p> 609 * 610 * @param minLengthInclusive The inclusive minimum length of the string to generate. 611 * @param maxLengthExclusive The exclusive maximum length of the string to generate. 612 * @return The random string. 613 * @since 3.5 614 * @deprecated Use {@link #nextGraph(int, int)} from {@link #secure()}, {@link #secureStrong()}, or {@link #insecure()}. 615 */ 616 @Deprecated 617 public static String randomGraph(final int minLengthInclusive, final int maxLengthExclusive) { 618 return secure().nextGraph(minLengthInclusive, maxLengthExclusive); 619 } 620 621 /** 622 * Creates a random string whose length is the number of characters specified. 623 * 624 * <p> 625 * Characters will be chosen from the set of numeric characters. 626 * </p> 627 * 628 * @param count The length of random string to create. 629 * @return The random string. 630 * @throws IllegalArgumentException Thrown if {@code count} < 0. 631 * @deprecated Use {@link #nextNumeric(int)} from {@link #secure()}, {@link #secureStrong()}, or {@link #insecure()}. 632 */ 633 @Deprecated 634 public static String randomNumeric(final int count) { 635 return secure().nextNumeric(count); 636 } 637 638 /** 639 * Creates a random string whose length is between the inclusive minimum and the exclusive maximum. 640 * 641 * <p> 642 * Characters will be chosen from the set of \p{Digit} characters. 643 * </p> 644 * 645 * @param minLengthInclusive The inclusive minimum length of the string to generate. 646 * @param maxLengthExclusive The exclusive maximum length of the string to generate. 647 * @return The random string. 648 * @since 3.5 649 * @deprecated Use {@link #nextNumeric(int, int)} from {@link #secure()}, {@link #secureStrong()}, or {@link #insecure()}. 650 */ 651 @Deprecated 652 public static String randomNumeric(final int minLengthInclusive, final int maxLengthExclusive) { 653 return secure().nextNumeric(minLengthInclusive, maxLengthExclusive); 654 } 655 656 /** 657 * Creates a random string whose length is the number of characters specified. 658 * 659 * <p> 660 * Characters will be chosen from the set of characters which match the POSIX [:print:] regular expression character 661 * class. This class includes all visible ASCII characters and spaces (i.e. anything except control characters). 662 * </p> 663 * 664 * @param count The length of random string to create. 665 * @return The random string. 666 * @throws IllegalArgumentException Thrown if {@code count} < 0. 667 * @since 3.5 668 * @deprecated Use {@link #nextPrint(int)} from {@link #secure()}, {@link #secureStrong()}, or {@link #insecure()}. 669 */ 670 @Deprecated 671 public static String randomPrint(final int count) { 672 return secure().nextPrint(count); 673 } 674 675 /** 676 * Creates a random string whose length is between the inclusive minimum and the exclusive maximum. 677 * 678 * <p> 679 * Characters will be chosen from the set of \p{Print} characters. 680 * </p> 681 * 682 * @param minLengthInclusive The inclusive minimum length of the string to generate. 683 * @param maxLengthExclusive The exclusive maximum length of the string to generate. 684 * @return The random string. 685 * @since 3.5 686 * @deprecated Use {@link #nextPrint(int, int)} from {@link #secure()}, {@link #secureStrong()}, or {@link #insecure()}. 687 */ 688 @Deprecated 689 public static String randomPrint(final int minLengthInclusive, final int maxLengthExclusive) { 690 return secure().nextPrint(minLengthInclusive, maxLengthExclusive); 691 } 692 693 /** 694 * Gets the singleton instance based on {@link SecureRandom#SecureRandom()} which uses a secure random number generator (RNG) implementing the default 695 * random number algorithm. 696 * <p> 697 * The method {@link SecureRandom#SecureRandom()} is called on-demand. 698 * </p> 699 * 700 * @return The singleton instance based on {@link SecureRandom#SecureRandom()}. 701 * @see SecureRandom#SecureRandom() 702 * @since 3.16.0 703 */ 704 public static RandomStringUtils secure() { 705 return SECURE; 706 } 707 708 /** 709 * Gets the singleton instance based on {@link SecureRandom#getInstanceStrong()} which uses an algorithms/providers 710 * specified in the {@code securerandom.strongAlgorithms} {@link Security} property. 711 * <p> 712 * The method {@link SecureRandom#getInstanceStrong()} is called on-demand. 713 * </p> 714 * 715 * @return The singleton instance based on {@link SecureRandom#getInstanceStrong()}. 716 * @see SecureRandom#getInstanceStrong() 717 * @since 3.17.0 718 */ 719 public static RandomStringUtils secureStrong() { 720 return SECURE_STRONG; 721 } 722 723 private final Supplier<RandomUtils> random; 724 725 /** 726 * {@link RandomStringUtils} instances should NOT be constructed in standard programming. Instead, the class should 727 * be used as {@code RandomStringUtils.random(5);}. 728 * 729 * <p> 730 * This constructor is public to permit tools that require a JavaBean instance to operate. 731 * </p> 732 * 733 * @deprecated TODO Make private in 4.0. 734 */ 735 @Deprecated 736 public RandomStringUtils() { 737 this(SECURE_SUPPLIER); 738 } 739 740 private RandomStringUtils(final Supplier<RandomUtils> random) { 741 this.random = random; 742 } 743 744 /** 745 * Creates a random string whose length is the number of characters specified. 746 * 747 * <p> 748 * Characters will be chosen from the set of all characters. 749 * </p> 750 * 751 * @param count The length of random string to create. 752 * @return The random string. 753 * @throws IllegalArgumentException Thrown if {@code count} < 0. 754 * @since 3.16.0 755 */ 756 public String next(final int count) { 757 return next(count, false, false); 758 } 759 760 /** 761 * Creates a random string whose length is the number of characters specified. 762 * 763 * <p> 764 * Characters will be chosen from the set of alphanumeric characters as indicated by the arguments. 765 * </p> 766 * 767 * @param count The length of random string to create. 768 * @param letters if {@code true}, generated string may include alphabetic characters. 769 * @param numbers if {@code true}, generated string may include numeric characters. 770 * @return The random string. 771 * @throws IllegalArgumentException Thrown if {@code count} < 0. 772 * @since 3.16.0 773 */ 774 public String next(final int count, final boolean letters, final boolean numbers) { 775 return next(count, 0, 0, letters, numbers); 776 } 777 778 /** 779 * Creates a random string whose length is the number of characters specified. 780 * 781 * <p> 782 * Characters will be chosen from the set of characters specified. 783 * </p> 784 * 785 * @param count The length of random string to create. 786 * @param chars The character array containing the set of characters to use, may be null. 787 * @return The random string. 788 * @throws IllegalArgumentException Thrown if {@code count} < 0. 789 * @since 3.16.0 790 */ 791 public String next(final int count, final char... chars) { 792 if (chars == null) { 793 return random(count, 0, 0, false, false, null, random()); 794 } 795 return random(count, 0, chars.length, false, false, chars, random()); 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 alphanumeric characters as indicated by the arguments. 803 * </p> 804 * 805 * @param count The length of random string to create. 806 * @param start The position in set of chars to start at. 807 * @param end The position in set of chars to end before. 808 * @param letters if {@code true}, generated string may include alphabetic characters. 809 * @param numbers if {@code true}, generated string may include numeric characters. 810 * @return The random string. 811 * @throws IllegalArgumentException Thrown if {@code count} < 0. 812 * @since 3.16.0 813 */ 814 public String next(final int count, final int start, final int end, final boolean letters, final boolean numbers) { 815 return random(count, start, end, letters, numbers, null, random()); 816 } 817 818 /** 819 * Creates a random string based on a variety of options, using default source of randomness. 820 * 821 * <p> 822 * This method has exactly the same semantics as {@link #random(int,int,int,boolean,boolean,char[],Random)}, but 823 * instead of using an externally supplied source of randomness, it uses the internal static {@link Random} 824 * instance. 825 * </p> 826 * 827 * @param count The length of random string to create. 828 * @param start The position in set of chars to start at. 829 * @param end The position in set of chars to end before. 830 * @param letters if {@code true}, generated string may include alphabetic characters. 831 * @param numbers if {@code true}, generated string may include numeric characters. 832 * @param chars The set of chars to choose randoms from. If {@code null}, then it will use the set of all chars. 833 * @return The random string. 834 * @throws ArrayIndexOutOfBoundsException Thrown if there are not {@code (end - start) + 1} characters in the set array. 835 * @throws IllegalArgumentException Thrown if {@code count} < 0. 836 */ 837 public String next(final int count, final int start, final int end, final boolean letters, final boolean numbers, 838 final char... chars) { 839 return random(count, start, end, letters, numbers, chars, random()); 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 specified by the string, must not be empty. If null, the set 847 * of all characters is used. 848 * </p> 849 * 850 * @param count The length of random string to create. 851 * @param chars The String containing the set of characters to use, may be null, but must not be empty. 852 * @return The random string. 853 * @throws IllegalArgumentException Thrown if {@code count} < 0 or the string is empty. 854 * @since 3.16.0 855 */ 856 public String next(final int count, final String chars) { 857 if (chars == null) { 858 return random(count, 0, 0, false, false, null, random()); 859 } 860 return next(count, chars.toCharArray()); 861 } 862 863 /** 864 * Creates a random string whose length is the number of characters specified. 865 * 866 * <p> 867 * Characters will be chosen from the set of Latin alphabetic characters (a-z, A-Z). 868 * </p> 869 * 870 * @param count The length of random string to create. 871 * @return The random string. 872 * @throws IllegalArgumentException Thrown if {@code count} < 0. 873 */ 874 public String nextAlphabetic(final int count) { 875 return next(count, true, false); 876 } 877 878 /** 879 * Creates a random string whose length is between the inclusive minimum and the exclusive maximum. 880 * 881 * <p> 882 * Characters will be chosen from the set of Latin alphabetic characters (a-z, A-Z). 883 * </p> 884 * 885 * @param minLengthInclusive The inclusive minimum length of the string to generate. 886 * @param maxLengthExclusive The exclusive maximum length of the string to generate. 887 * @return The random string. 888 * @since 3.5 889 */ 890 public String nextAlphabetic(final int minLengthInclusive, final int maxLengthExclusive) { 891 return nextAlphabetic(randomUtils().randomInt(minLengthInclusive, maxLengthExclusive)); 892 } 893 894 /** 895 * Creates a random string whose length is the number of characters specified. 896 * 897 * <p> 898 * Characters will be chosen from the set of Latin alphabetic characters (a-z, A-Z) and the digits 0-9. 899 * </p> 900 * 901 * @param count The length of random string to create. 902 * @return The random string. 903 * @throws IllegalArgumentException Thrown if {@code count} < 0. 904 */ 905 public String nextAlphanumeric(final int count) { 906 return next(count, true, true); 907 } 908 909 /** 910 * Creates a random string whose length is between the inclusive minimum and the exclusive maximum. 911 * 912 * <p> 913 * Characters will be chosen from the set of Latin alphabetic characters (a-z, A-Z) and the digits 0-9. 914 * </p> 915 * 916 * @param minLengthInclusive The inclusive minimum length of the string to generate. 917 * @param maxLengthExclusive The exclusive maximum length of the string to generate. 918 * @return The random string. 919 * @since 3.5 920 */ 921 public String nextAlphanumeric(final int minLengthInclusive, final int maxLengthExclusive) { 922 return nextAlphanumeric(randomUtils().randomInt(minLengthInclusive, maxLengthExclusive)); 923 } 924 925 /** 926 * Creates a random string whose length is the number of characters specified. 927 * 928 * <p> 929 * Characters will be chosen from the set of characters whose ASCII value is between {@code 32} and {@code 126} 930 * (inclusive). 931 * </p> 932 * 933 * @param count The length of random string to create. 934 * @return The random string. 935 * @throws IllegalArgumentException Thrown if {@code count} < 0. 936 */ 937 public String nextAscii(final int count) { 938 return next(count, 32, 127, false, false); 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 characters whose ASCII value is between {@code 32} and {@code 126} 946 * (inclusive). 947 * </p> 948 * 949 * @param minLengthInclusive The inclusive minimum length of the string to generate. 950 * @param maxLengthExclusive The exclusive maximum length of the string to generate. 951 * @return The random string. 952 * @since 3.5 953 */ 954 public String nextAscii(final int minLengthInclusive, final int maxLengthExclusive) { 955 return nextAscii(randomUtils().randomInt(minLengthInclusive, maxLengthExclusive)); 956 } 957 958 /** 959 * Creates a random string whose length is the number of characters specified. 960 * 961 * <p> 962 * Characters will be chosen from the set of characters which match the POSIX [:graph:] regular expression character 963 * class. This class contains all visible ASCII characters (i.e. anything except spaces and control characters). 964 * </p> 965 * 966 * @param count The length of random string to create. 967 * @return The random string. 968 * @throws IllegalArgumentException Thrown if {@code count} < 0. 969 * @since 3.5 970 */ 971 public String nextGraph(final int count) { 972 return next(count, 33, 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{Graph} 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.5 986 */ 987 public String nextGraph(final int minLengthInclusive, final int maxLengthExclusive) { 988 return nextGraph(randomUtils().randomInt(minLengthInclusive, maxLengthExclusive)); 989 } 990 991 /** 992 * Creates a random string whose length is the number of characters specified. 993 * 994 * <p> 995 * Characters will be chosen from the set of numeric characters. 996 * </p> 997 * 998 * @param count The length of random string to create. 999 * @return The random string. 1000 * @throws IllegalArgumentException Thrown if {@code count} < 0. 1001 */ 1002 public String nextNumeric(final int count) { 1003 return next(count, false, true); 1004 } 1005 1006 /** 1007 * Creates a random string whose length is between the inclusive minimum and the exclusive maximum. 1008 * 1009 * <p> 1010 * Characters will be chosen from the set of \p{Digit} characters. 1011 * </p> 1012 * 1013 * @param minLengthInclusive The inclusive minimum length of the string to generate. 1014 * @param maxLengthExclusive The exclusive maximum length of the string to generate. 1015 * @return The random string. 1016 * @since 3.5 1017 */ 1018 public String nextNumeric(final int minLengthInclusive, final int maxLengthExclusive) { 1019 return nextNumeric(randomUtils().randomInt(minLengthInclusive, maxLengthExclusive)); 1020 } 1021 1022 /** 1023 * Creates a random string whose length is the number of characters specified. 1024 * 1025 * <p> 1026 * Characters will be chosen from the set of characters which match the POSIX [:print:] regular expression character 1027 * class. This class includes all visible ASCII characters and spaces (i.e. anything except control characters). 1028 * </p> 1029 * 1030 * @param count The length of random string to create. 1031 * @return The random string. 1032 * @throws IllegalArgumentException Thrown if {@code count} < 0. 1033 * @since 3.5 1034 * @since 3.16.0 1035 */ 1036 public String nextPrint(final int count) { 1037 return next(count, 32, 126, false, false); 1038 } 1039 1040 /** 1041 * Creates a random string whose length is between the inclusive minimum and the exclusive maximum. 1042 * 1043 * <p> 1044 * Characters will be chosen from the set of \p{Print} characters. 1045 * </p> 1046 * 1047 * @param minLengthInclusive The inclusive minimum length of the string to generate. 1048 * @param maxLengthExclusive The exclusive maximum length of the string to generate. 1049 * @return The random string. 1050 * @since 3.16.0 1051 */ 1052 public String nextPrint(final int minLengthInclusive, final int maxLengthExclusive) { 1053 return nextPrint(randomUtils().randomInt(minLengthInclusive, maxLengthExclusive)); 1054 } 1055 1056 /** 1057 * Gets the Random. 1058 * 1059 * @return The Random. 1060 */ 1061 private Random random() { 1062 return randomUtils().random(); 1063 } 1064 1065 /** 1066 * Gets the RandomUtils. 1067 * 1068 * @return The RandomUtils. 1069 */ 1070 private RandomUtils randomUtils() { 1071 return random.get(); 1072 } 1073 1074 @Override 1075 public String toString() { 1076 return "RandomStringUtils [random=" + random() + "]"; 1077 } 1078 1079}