1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 package org.apache.commons.lang3; 18 19 import java.util.Random; 20 import java.util.concurrent.ThreadLocalRandom; 21 22 /** 23 * Generates random {@link String}s. 24 * 25 * <p><b>Caveat: Instances of {@link Random}, upon which the implementation of this 26 * class relies, are not cryptographically secure.</b></p> 27 * 28 * <p>RandomStringUtils is intended for simple use cases. For more advanced 29 * use cases consider using Apache Commons Text's 30 * <a href="https://commons.apache.org/proper/commons-text/javadocs/api-release/org/apache/commons/text/RandomStringGenerator.html"> 31 * RandomStringGenerator</a> instead.</p> 32 * 33 * <p>The Apache Commons project provides 34 * <a href="https://commons.apache.org/proper/commons-rng/">Commons RNG</a> dedicated to pseudo-random number generation, that may be 35 * a better choice for applications with more stringent requirements 36 * (performance and/or correctness).</p> 37 * 38 * <p>Note that <em>private high surrogate</em> characters are ignored. 39 * These are Unicode characters that fall between the values 56192 (db80) 40 * and 56319 (dbff) as we don't know how to handle them. 41 * High and low surrogates are correctly dealt with - that is if a 42 * high surrogate is randomly chosen, 55296 (d800) to 56191 (db7f) 43 * then it is followed by a low surrogate. If a low surrogate is chosen, 44 * 56320 (dc00) to 57343 (dfff) then it is placed after a randomly 45 * chosen high surrogate.</p> 46 * 47 * <p>#ThreadSafe#</p> 48 * @since 1.0 49 */ 50 public class RandomStringUtils { 51 random()52 private static ThreadLocalRandom random() { 53 return ThreadLocalRandom.current(); 54 } 55 56 // Random 57 /** 58 * Creates a random string whose length is the number of characters 59 * specified. 60 * 61 * <p>Characters will be chosen from the set of all characters.</p> 62 * 63 * @param count the length of random string to create 64 * @return the random string 65 */ random(final int count)66 public static String random(final int count) { 67 return random(count, false, false); 68 } 69 70 /** 71 * Creates a random string whose length is the number of characters 72 * specified. 73 * 74 * <p>Characters will be chosen from the set of alpha-numeric 75 * characters as indicated by the arguments.</p> 76 * 77 * @param count the length of random string to create 78 * @param letters if {@code true}, generated string may include 79 * alphabetic characters 80 * @param numbers if {@code true}, generated string may include 81 * numeric characters 82 * @return the random string 83 */ random(final int count, final boolean letters, final boolean numbers)84 public static String random(final int count, final boolean letters, final boolean numbers) { 85 return random(count, 0, 0, letters, numbers); 86 } 87 88 /** 89 * Creates a random string whose length is the number of characters 90 * specified. 91 * 92 * <p>Characters will be chosen from the set of characters specified.</p> 93 * 94 * @param count the length of random string to create 95 * @param chars the character array containing the set of characters to use, 96 * may be null 97 * @return the random string 98 * @throws IllegalArgumentException if {@code count} < 0. 99 */ random(final int count, final char... chars)100 public static String random(final int count, final char... chars) { 101 if (chars == null) { 102 return random(count, 0, 0, false, false, null, random()); 103 } 104 return random(count, 0, chars.length, false, false, chars, random()); 105 } 106 107 /** 108 * Creates a random string whose length is the number of characters 109 * specified. 110 * 111 * <p>Characters will be chosen from the set of alpha-numeric 112 * characters as indicated by the arguments.</p> 113 * 114 * @param count the length of random string to create 115 * @param start the position in set of chars to start at 116 * @param end the position in set of chars to end before 117 * @param letters if {@code true}, generated string may include 118 * alphabetic characters 119 * @param numbers if {@code true}, generated string may include 120 * numeric characters 121 * @return the random string 122 */ random(final int count, final int start, final int end, final boolean letters, final boolean numbers)123 public static String random(final int count, final int start, final int end, final boolean letters, final boolean numbers) { 124 return random(count, start, end, letters, numbers, null, random()); 125 } 126 127 /** 128 * Creates a random string based on a variety of options, using 129 * default source of randomness. 130 * 131 * <p>This method has exactly the same semantics as 132 * {@link #random(int,int,int,boolean,boolean,char[],Random)}, but 133 * instead of using an externally supplied source of randomness, it uses 134 * the internal static {@link Random} instance.</p> 135 * 136 * @param count the length of random string to create 137 * @param start the position in set of chars to start at 138 * @param end the position in set of chars to end before 139 * @param letters if {@code true}, generated string may include 140 * alphabetic characters 141 * @param numbers if {@code true}, generated string may include 142 * numeric characters 143 * @param chars the set of chars to choose randoms from. 144 * If {@code null}, then it will use the set of all chars. 145 * @return the random string 146 * @throws ArrayIndexOutOfBoundsException if there are not 147 * {@code (end - start) + 1} characters in the set array. 148 */ random(final int count, final int start, final int end, final boolean letters, final boolean numbers, final char... chars)149 public static String random(final int count, final int start, final int end, final boolean letters, final boolean numbers, final char... chars) { 150 return random(count, start, end, letters, numbers, chars, random()); 151 } 152 153 /** 154 * Creates a random string based on a variety of options, using 155 * supplied source of randomness. 156 * 157 * <p>If start and end are both {@code 0}, start and end are set 158 * to {@code ' '} and {@code 'z'}, the ASCII printable 159 * characters, will be used, unless letters and numbers are both 160 * {@code false}, in which case, start and end are set to 161 * {@code 0} and {@link Character#MAX_CODE_POINT}. 162 * 163 * <p>If set is not {@code null}, characters between start and 164 * end are chosen.</p> 165 * 166 * <p>This method accepts a user-supplied {@link Random} 167 * instance to use as a source of randomness. By seeding a single 168 * {@link Random} instance with a fixed seed and using it for each call, 169 * the same random sequence of strings can be generated repeatedly 170 * and predictably.</p> 171 * 172 * @param count the length of random string to create 173 * @param start the position in set of chars to start at (inclusive) 174 * @param end the position in set of chars to end before (exclusive) 175 * @param letters if {@code true}, generated string may include 176 * alphabetic characters 177 * @param numbers if {@code true}, generated string may include 178 * numeric characters 179 * @param chars the set of chars to choose randoms from, must not be empty. 180 * If {@code null}, then it will use the set of all chars. 181 * @param random a source of randomness. 182 * @return the random string 183 * @throws ArrayIndexOutOfBoundsException if there are not 184 * {@code (end - start) + 1} characters in the set array. 185 * @throws IllegalArgumentException if {@code count} < 0 or the provided chars array is empty. 186 * @since 2.0 187 */ random(int count, int start, int end, final boolean letters, final boolean numbers, final char[] chars, final Random random)188 public static String random(int count, int start, int end, final boolean letters, final boolean numbers, 189 final char[] chars, final Random random) { 190 if (count == 0) { 191 return StringUtils.EMPTY; 192 } 193 if (count < 0) { 194 throw new IllegalArgumentException("Requested random string length " + count + " is less than 0."); 195 } 196 if (chars != null && chars.length == 0) { 197 throw new IllegalArgumentException("The chars array must not be empty"); 198 } 199 200 if (start == 0 && end == 0) { 201 if (chars != null) { 202 end = chars.length; 203 } else if (!letters && !numbers) { 204 end = Character.MAX_CODE_POINT; 205 } else { 206 end = 'z' + 1; 207 start = ' '; 208 } 209 } else if (end <= start) { 210 throw new IllegalArgumentException("Parameter end (" + end + ") must be greater than start (" + start + ")"); 211 } 212 213 final int zero_digit_ascii = 48; 214 final int first_letter_ascii = 65; 215 216 if (chars == null && (numbers && end <= zero_digit_ascii 217 || letters && end <= first_letter_ascii)) { 218 throw new IllegalArgumentException("Parameter end (" + end + ") must be greater then (" + zero_digit_ascii + ") for generating digits " + 219 "or greater then (" + first_letter_ascii + ") for generating letters."); 220 } 221 222 final StringBuilder builder = new StringBuilder(count); 223 final int gap = end - start; 224 225 while (count-- != 0) { 226 final int codePoint; 227 if (chars == null) { 228 codePoint = random.nextInt(gap) + start; 229 230 switch (Character.getType(codePoint)) { 231 case Character.UNASSIGNED: 232 case Character.PRIVATE_USE: 233 case Character.SURROGATE: 234 count++; 235 continue; 236 } 237 238 } else { 239 codePoint = chars[random.nextInt(gap) + start]; 240 } 241 242 final int numberOfChars = Character.charCount(codePoint); 243 if (count == 0 && numberOfChars > 1) { 244 count++; 245 continue; 246 } 247 248 if (letters && Character.isLetter(codePoint) 249 || numbers && Character.isDigit(codePoint) 250 || !letters && !numbers) { 251 builder.appendCodePoint(codePoint); 252 253 if (numberOfChars == 2) { 254 count--; 255 } 256 257 } else { 258 count++; 259 } 260 } 261 return builder.toString(); 262 } 263 264 /** 265 * Creates a random string whose length is the number of characters 266 * specified. 267 * 268 * <p>Characters will be chosen from the set of characters 269 * specified by the string, must not be empty. 270 * If null, the set of all characters is used.</p> 271 * 272 * @param count the length of random string to create 273 * @param chars the String containing the set of characters to use, 274 * may be null, but must not be empty 275 * @return the random string 276 * @throws IllegalArgumentException if {@code count} < 0 or the string is empty. 277 */ random(final int count, final String chars)278 public static String random(final int count, final String chars) { 279 if (chars == null) { 280 return random(count, 0, 0, false, false, null, random()); 281 } 282 return random(count, chars.toCharArray()); 283 } 284 285 /** 286 * Creates a random string whose length is the number of characters 287 * specified. 288 * 289 * <p>Characters will be chosen from the set of Latin alphabetic 290 * characters (a-z, A-Z).</p> 291 * 292 * @param count the length of random string to create 293 * @return the random string 294 */ randomAlphabetic(final int count)295 public static String randomAlphabetic(final int count) { 296 return random(count, true, false); 297 } 298 299 /** 300 * Creates a random string whose length is between the inclusive minimum and 301 * the exclusive maximum. 302 * 303 * <p>Characters will be chosen from the set of Latin alphabetic characters (a-z, A-Z).</p> 304 * 305 * @param minLengthInclusive the inclusive minimum length of the string to generate 306 * @param maxLengthExclusive the exclusive maximum length of the string to generate 307 * @return the random string 308 * @since 3.5 309 */ randomAlphabetic(final int minLengthInclusive, final int maxLengthExclusive)310 public static String randomAlphabetic(final int minLengthInclusive, final int maxLengthExclusive) { 311 return randomAlphabetic(RandomUtils.nextInt(minLengthInclusive, maxLengthExclusive)); 312 } 313 314 /** 315 * Creates a random string whose length is the number of characters 316 * specified. 317 * 318 * <p>Characters will be chosen from the set of Latin alphabetic 319 * characters (a-z, A-Z) and the digits 0-9.</p> 320 * 321 * @param count the length of random string to create 322 * @return the random string 323 */ randomAlphanumeric(final int count)324 public static String randomAlphanumeric(final int count) { 325 return random(count, true, true); 326 } 327 328 /** 329 * Creates a random string whose length is between the inclusive minimum and 330 * the exclusive maximum. 331 * 332 * <p>Characters will be chosen from the set of Latin alphabetic 333 * characters (a-z, A-Z) and the digits 0-9.</p> 334 * 335 * @param minLengthInclusive the inclusive minimum length of the string to generate 336 * @param maxLengthExclusive the exclusive maximum length of the string to generate 337 * @return the random string 338 * @since 3.5 339 */ randomAlphanumeric(final int minLengthInclusive, final int maxLengthExclusive)340 public static String randomAlphanumeric(final int minLengthInclusive, final int maxLengthExclusive) { 341 return randomAlphanumeric(RandomUtils.nextInt(minLengthInclusive, maxLengthExclusive)); 342 } 343 344 /** 345 * Creates a random string whose length is the number of characters 346 * specified. 347 * 348 * <p>Characters will be chosen from the set of characters whose 349 * ASCII value is between {@code 32} and {@code 126} (inclusive).</p> 350 * 351 * @param count the length of random string to create 352 * @return the random string 353 */ randomAscii(final int count)354 public static String randomAscii(final int count) { 355 return random(count, 32, 127, false, false); 356 } 357 358 /** 359 * Creates a random string whose length is between the inclusive minimum and 360 * the exclusive maximum. 361 * 362 * <p>Characters will be chosen from the set of characters whose 363 * ASCII value is between {@code 32} and {@code 126} (inclusive).</p> 364 * 365 * @param minLengthInclusive the inclusive minimum length of the string to generate 366 * @param maxLengthExclusive the exclusive maximum length of the string to generate 367 * @return the random string 368 * @since 3.5 369 */ randomAscii(final int minLengthInclusive, final int maxLengthExclusive)370 public static String randomAscii(final int minLengthInclusive, final int maxLengthExclusive) { 371 return randomAscii(RandomUtils.nextInt(minLengthInclusive, maxLengthExclusive)); 372 } 373 374 /** 375 * Creates a random string whose length is the number of characters specified. 376 * 377 * <p>Characters will be chosen from the set of characters which match the POSIX [:graph:] 378 * regular expression character class. This class contains all visible ASCII characters 379 * (i.e. anything except spaces and control characters).</p> 380 * 381 * @param count the length of random string to create 382 * @return the random string 383 * @since 3.5 384 */ randomGraph(final int count)385 public static String randomGraph(final int count) { 386 return random(count, 33, 126, false, false); 387 } 388 389 /** 390 * Creates a random string whose length is between the inclusive minimum and 391 * the exclusive maximum. 392 * 393 * <p>Characters will be chosen from the set of \p{Graph} characters.</p> 394 * 395 * @param minLengthInclusive the inclusive minimum length of the string to generate 396 * @param maxLengthExclusive the exclusive maximum length of the string to generate 397 * @return the random string 398 * @since 3.5 399 */ randomGraph(final int minLengthInclusive, final int maxLengthExclusive)400 public static String randomGraph(final int minLengthInclusive, final int maxLengthExclusive) { 401 return randomGraph(RandomUtils.nextInt(minLengthInclusive, maxLengthExclusive)); 402 } 403 404 /** 405 * Creates a random string whose length is the number of characters 406 * specified. 407 * 408 * <p>Characters will be chosen from the set of numeric 409 * characters.</p> 410 * 411 * @param count the length of random string to create 412 * @return the random string 413 */ randomNumeric(final int count)414 public static String randomNumeric(final int count) { 415 return random(count, false, true); 416 } 417 418 /** 419 * Creates a random string whose length is between the inclusive minimum and 420 * the exclusive maximum. 421 * 422 * <p>Characters will be chosen from the set of \p{Digit} characters.</p> 423 * 424 * @param minLengthInclusive the inclusive minimum length of the string to generate 425 * @param maxLengthExclusive the exclusive maximum length of the string to generate 426 * @return the random string 427 * @since 3.5 428 */ randomNumeric(final int minLengthInclusive, final int maxLengthExclusive)429 public static String randomNumeric(final int minLengthInclusive, final int maxLengthExclusive) { 430 return randomNumeric(RandomUtils.nextInt(minLengthInclusive, maxLengthExclusive)); 431 } 432 433 /** 434 * Creates a random string whose length is the number of characters specified. 435 * 436 * <p>Characters will be chosen from the set of characters which match the POSIX [:print:] 437 * regular expression character class. This class includes all visible ASCII characters and spaces 438 * (i.e. anything except control characters).</p> 439 * 440 * @param count the length of random string to create 441 * @return the random string 442 * @since 3.5 443 */ randomPrint(final int count)444 public static String randomPrint(final int count) { 445 return random(count, 32, 126, false, false); 446 } 447 448 449 /** 450 * Creates a random string whose length is between the inclusive minimum and 451 * the exclusive maximum. 452 * 453 * <p>Characters will be chosen from the set of \p{Print} characters.</p> 454 * 455 * @param minLengthInclusive the inclusive minimum length of the string to generate 456 * @param maxLengthExclusive the exclusive maximum length of the string to generate 457 * @return the random string 458 * @since 3.5 459 */ randomPrint(final int minLengthInclusive, final int maxLengthExclusive)460 public static String randomPrint(final int minLengthInclusive, final int maxLengthExclusive) { 461 return randomPrint(RandomUtils.nextInt(minLengthInclusive, maxLengthExclusive)); 462 } 463 464 /** 465 * {@link RandomStringUtils} instances should NOT be constructed in 466 * standard programming. Instead, the class should be used as 467 * {@code RandomStringUtils.random(5);}. 468 * 469 * <p>This constructor is public to permit tools that require a JavaBean instance 470 * to operate.</p> 471 */ RandomStringUtils()472 public RandomStringUtils() { 473 } 474 475 } 476