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 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 * @throws IllegalArgumentException if {@code count} < 0. 66 */ 67 public static String random(final int count) { 68 return random(count, false, false); 69 } 70 71 /** 72 * Creates a random string whose length is the number of characters 73 * specified. 74 * 75 * <p>Characters will be chosen from the set of alpha-numeric 76 * characters as indicated by the arguments.</p> 77 * 78 * @param count the length of random string to create 79 * @param letters if {@code true}, generated string may include 80 * alphabetic characters 81 * @param numbers if {@code true}, generated string may include 82 * numeric characters 83 * @return the random string 84 * @throws IllegalArgumentException if {@code count} < 0. 85 */ 86 public static String random(final int count, final boolean letters, final boolean numbers) { 87 return random(count, 0, 0, letters, numbers); 88 } 89 90 /** 91 * Creates a random string whose length is the number of characters 92 * specified. 93 * 94 * <p>Characters will be chosen from the set of characters specified.</p> 95 * 96 * @param count the length of random string to create 97 * @param chars the character array containing the set of characters to use, 98 * may be null 99 * @return the random string 100 * @throws IllegalArgumentException if {@code count} < 0. 101 */ 102 public static String random(final int count, final char... chars) { 103 if (chars == null) { 104 return random(count, 0, 0, false, false, null, random()); 105 } 106 return random(count, 0, chars.length, false, false, chars, random()); 107 } 108 109 /** 110 * Creates a random string whose length is the number of characters 111 * specified. 112 * 113 * <p>Characters will be chosen from the set of alpha-numeric 114 * characters as indicated by the arguments.</p> 115 * 116 * @param count the length of random string to create 117 * @param start the position in set of chars to start at 118 * @param end the position in set of chars to end before 119 * @param letters if {@code true}, generated string may include 120 * alphabetic characters 121 * @param numbers if {@code true}, generated string may include 122 * numeric characters 123 * @return the random string 124 * @throws IllegalArgumentException if {@code count} < 0. 125 */ 126 public static String random(final int count, final int start, final int end, final boolean letters, final boolean numbers) { 127 return random(count, start, end, letters, numbers, null, random()); 128 } 129 130 /** 131 * Creates a random string based on a variety of options, using 132 * default source of randomness. 133 * 134 * <p>This method has exactly the same semantics as 135 * {@link #random(int,int,int,boolean,boolean,char[],Random)}, but 136 * instead of using an externally supplied source of randomness, it uses 137 * the internal static {@link Random} instance.</p> 138 * 139 * @param count the length of random string to create 140 * @param start the position in set of chars to start at 141 * @param end the position in set of chars to end before 142 * @param letters if {@code true}, generated string may include 143 * alphabetic characters 144 * @param numbers if {@code true}, generated string may include 145 * numeric characters 146 * @param chars the set of chars to choose randoms from. 147 * If {@code null}, then it will use the set of all chars. 148 * @return the random string 149 * @throws ArrayIndexOutOfBoundsException if there are not 150 * {@code (end - start) + 1} characters in the set array. 151 * @throws IllegalArgumentException if {@code count} < 0. 152 */ 153 public static String random(final int count, final int start, final int end, final boolean letters, final boolean numbers, final char... chars) { 154 return random(count, start, end, letters, numbers, chars, random()); 155 } 156 157 /** 158 * Creates a random string based on a variety of options, using 159 * supplied source of randomness. 160 * 161 * <p>If start and end are both {@code 0}, start and end are set 162 * to {@code ' '} and {@code 'z'}, the ASCII printable 163 * characters, will be used, unless letters and numbers are both 164 * {@code false}, in which case, start and end are set to 165 * {@code 0} and {@link Character#MAX_CODE_POINT}. 166 * 167 * <p>If set is not {@code null}, characters between start and 168 * end are chosen.</p> 169 * 170 * <p>This method accepts a user-supplied {@link Random} 171 * instance to use as a source of randomness. By seeding a single 172 * {@link Random} instance with a fixed seed and using it for each call, 173 * the same random sequence of strings can be generated repeatedly 174 * and predictably.</p> 175 * 176 * @param count the length of random string to create 177 * @param start the position in set of chars to start at (inclusive) 178 * @param end the position in set of chars to end before (exclusive) 179 * @param letters if {@code true}, generated string may include 180 * alphabetic characters 181 * @param numbers if {@code true}, generated string may include 182 * numeric characters 183 * @param chars the set of chars to choose randoms from, must not be empty. 184 * If {@code null}, then it will use the set of all chars. 185 * @param random a source of randomness. 186 * @return the random string 187 * @throws ArrayIndexOutOfBoundsException if there are not 188 * {@code (end - start) + 1} characters in the set array. 189 * @throws IllegalArgumentException if {@code count} < 0 or the provided chars array is empty. 190 * @since 2.0 191 */ 192 public static String random(int count, int start, int end, final boolean letters, final boolean numbers, 193 final char[] chars, final Random random) { 194 if (count == 0) { 195 return StringUtils.EMPTY; 196 } 197 if (count < 0) { 198 throw new IllegalArgumentException("Requested random string length " + count + " is less than 0."); 199 } 200 if (chars != null && chars.length == 0) { 201 throw new IllegalArgumentException("The chars array must not be empty"); 202 } 203 204 if (start == 0 && end == 0) { 205 if (chars != null) { 206 end = chars.length; 207 } else if (!letters && !numbers) { 208 end = Character.MAX_CODE_POINT; 209 } else { 210 end = 'z' + 1; 211 start = ' '; 212 } 213 } else if (end <= start) { 214 throw new IllegalArgumentException("Parameter end (" + end + ") must be greater than start (" + start + ")"); 215 } 216 217 final int zeroDigitAscii = 48; 218 final int firstLetterAscii = 65; 219 220 if (chars == null && (numbers && end <= zeroDigitAscii 221 || letters && end <= firstLetterAscii)) { 222 throw new IllegalArgumentException("Parameter end (" + end + ") must be greater then (" + zeroDigitAscii + ") for generating digits " + 223 "or greater then (" + firstLetterAscii + ") for generating letters."); 224 } 225 226 final StringBuilder builder = new StringBuilder(count); 227 final int gap = end - start; 228 229 while (count-- != 0) { 230 final int codePoint; 231 if (chars == null) { 232 codePoint = random.nextInt(gap) + start; 233 234 switch (Character.getType(codePoint)) { 235 case Character.UNASSIGNED: 236 case Character.PRIVATE_USE: 237 case Character.SURROGATE: 238 count++; 239 continue; 240 } 241 242 } else { 243 codePoint = chars[random.nextInt(gap) + start]; 244 } 245 246 final int numberOfChars = Character.charCount(codePoint); 247 if (count == 0 && numberOfChars > 1) { 248 count++; 249 continue; 250 } 251 252 if (letters && Character.isLetter(codePoint) 253 || numbers && Character.isDigit(codePoint) 254 || !letters && !numbers) { 255 builder.appendCodePoint(codePoint); 256 257 if (numberOfChars == 2) { 258 count--; 259 } 260 261 } else { 262 count++; 263 } 264 } 265 return builder.toString(); 266 } 267 268 /** 269 * Creates a random string whose length is the number of characters 270 * specified. 271 * 272 * <p>Characters will be chosen from the set of characters 273 * specified by the string, must not be empty. 274 * If null, the set of all characters is used.</p> 275 * 276 * @param count the length of random string to create 277 * @param chars the String containing the set of characters to use, 278 * may be null, but must not be empty 279 * @return the random string 280 * @throws IllegalArgumentException if {@code count} < 0 or the string is empty. 281 */ 282 public static String random(final int count, final String chars) { 283 if (chars == null) { 284 return random(count, 0, 0, false, false, null, random()); 285 } 286 return random(count, chars.toCharArray()); 287 } 288 289 /** 290 * Creates a random string whose length is the number of characters 291 * specified. 292 * 293 * <p>Characters will be chosen from the set of Latin alphabetic 294 * characters (a-z, A-Z).</p> 295 * 296 * @param count the length of random string to create 297 * @return the random string 298 * @throws IllegalArgumentException if {@code count} < 0. 299 */ 300 public static String randomAlphabetic(final int count) { 301 return random(count, true, false); 302 } 303 304 /** 305 * Creates a random string whose length is between the inclusive minimum and 306 * the exclusive maximum. 307 * 308 * <p>Characters will be chosen from the set of Latin alphabetic characters (a-z, A-Z).</p> 309 * 310 * @param minLengthInclusive the inclusive minimum length of the string to generate 311 * @param maxLengthExclusive the exclusive maximum length of the string to generate 312 * @return the random string 313 * @since 3.5 314 */ 315 public static String randomAlphabetic(final int minLengthInclusive, final int maxLengthExclusive) { 316 return randomAlphabetic(RandomUtils.nextInt(minLengthInclusive, maxLengthExclusive)); 317 } 318 319 /** 320 * Creates a random string whose length is the number of characters 321 * specified. 322 * 323 * <p>Characters will be chosen from the set of Latin alphabetic 324 * characters (a-z, A-Z) and the digits 0-9.</p> 325 * 326 * @param count the length of random string to create 327 * @return the random string 328 * @throws IllegalArgumentException if {@code count} < 0. 329 */ 330 public static String randomAlphanumeric(final int count) { 331 return random(count, true, true); 332 } 333 334 /** 335 * Creates a random string whose length is between the inclusive minimum and 336 * the exclusive maximum. 337 * 338 * <p>Characters will be chosen from the set of Latin alphabetic 339 * characters (a-z, A-Z) and the digits 0-9.</p> 340 * 341 * @param minLengthInclusive the inclusive minimum length of the string to generate 342 * @param maxLengthExclusive the exclusive maximum length of the string to generate 343 * @return the random string 344 * @since 3.5 345 */ 346 public static String randomAlphanumeric(final int minLengthInclusive, final int maxLengthExclusive) { 347 return randomAlphanumeric(RandomUtils.nextInt(minLengthInclusive, maxLengthExclusive)); 348 } 349 350 /** 351 * Creates a random string whose length is the number of characters 352 * specified. 353 * 354 * <p>Characters will be chosen from the set of characters whose 355 * ASCII value is between {@code 32} and {@code 126} (inclusive).</p> 356 * 357 * @param count the length of random string to create 358 * @return the random string 359 * @throws IllegalArgumentException if {@code count} < 0. 360 */ 361 public static String randomAscii(final int count) { 362 return random(count, 32, 127, false, false); 363 } 364 365 /** 366 * Creates a random string whose length is between the inclusive minimum and 367 * the exclusive maximum. 368 * 369 * <p>Characters will be chosen from the set of characters whose 370 * ASCII value is between {@code 32} and {@code 126} (inclusive).</p> 371 * 372 * @param minLengthInclusive the inclusive minimum length of the string to generate 373 * @param maxLengthExclusive the exclusive maximum length of the string to generate 374 * @return the random string 375 * @since 3.5 376 */ 377 public static String randomAscii(final int minLengthInclusive, final int maxLengthExclusive) { 378 return randomAscii(RandomUtils.nextInt(minLengthInclusive, maxLengthExclusive)); 379 } 380 381 /** 382 * Creates a random string whose length is the number of characters specified. 383 * 384 * <p>Characters will be chosen from the set of characters which match the POSIX [:graph:] 385 * regular expression character class. This class contains all visible ASCII characters 386 * (i.e. anything except spaces and control characters).</p> 387 * 388 * @param count the length of random string to create 389 * @return the random string 390 * @throws IllegalArgumentException if {@code count} < 0. 391 * @since 3.5 392 */ 393 public static String randomGraph(final int count) { 394 return random(count, 33, 126, false, false); 395 } 396 397 /** 398 * Creates a random string whose length is between the inclusive minimum and 399 * the exclusive maximum. 400 * 401 * <p>Characters will be chosen from the set of \p{Graph} characters.</p> 402 * 403 * @param minLengthInclusive the inclusive minimum length of the string to generate 404 * @param maxLengthExclusive the exclusive maximum length of the string to generate 405 * @return the random string 406 * @since 3.5 407 */ 408 public static String randomGraph(final int minLengthInclusive, final int maxLengthExclusive) { 409 return randomGraph(RandomUtils.nextInt(minLengthInclusive, maxLengthExclusive)); 410 } 411 412 /** 413 * Creates a random string whose length is the number of characters 414 * specified. 415 * 416 * <p>Characters will be chosen from the set of numeric 417 * characters.</p> 418 * 419 * @param count the length of random string to create 420 * @return the random string 421 * @throws IllegalArgumentException if {@code count} < 0. 422 */ 423 public static String randomNumeric(final int count) { 424 return random(count, false, true); 425 } 426 427 /** 428 * Creates a random string whose length is between the inclusive minimum and 429 * the exclusive maximum. 430 * 431 * <p>Characters will be chosen from the set of \p{Digit} characters.</p> 432 * 433 * @param minLengthInclusive the inclusive minimum length of the string to generate 434 * @param maxLengthExclusive the exclusive maximum length of the string to generate 435 * @return the random string 436 * @since 3.5 437 */ 438 public static String randomNumeric(final int minLengthInclusive, final int maxLengthExclusive) { 439 return randomNumeric(RandomUtils.nextInt(minLengthInclusive, maxLengthExclusive)); 440 } 441 442 /** 443 * Creates a random string whose length is the number of characters specified. 444 * 445 * <p>Characters will be chosen from the set of characters which match the POSIX [:print:] 446 * regular expression character class. This class includes all visible ASCII characters and spaces 447 * (i.e. anything except control characters).</p> 448 * 449 * @param count the length of random string to create 450 * @return the random string 451 * @throws IllegalArgumentException if {@code count} < 0. 452 * @since 3.5 453 */ 454 public static String randomPrint(final int count) { 455 return random(count, 32, 126, false, false); 456 } 457 458 459 /** 460 * Creates a random string whose length is between the inclusive minimum and 461 * the exclusive maximum. 462 * 463 * <p>Characters will be chosen from the set of \p{Print} characters.</p> 464 * 465 * @param minLengthInclusive the inclusive minimum length of the string to generate 466 * @param maxLengthExclusive the exclusive maximum length of the string to generate 467 * @return the random string 468 * @since 3.5 469 */ 470 public static String randomPrint(final int minLengthInclusive, final int maxLengthExclusive) { 471 return randomPrint(RandomUtils.nextInt(minLengthInclusive, maxLengthExclusive)); 472 } 473 474 /** 475 * {@link RandomStringUtils} instances should NOT be constructed in 476 * standard programming. Instead, the class should be used as 477 * {@code RandomStringUtils.random(5);}. 478 * 479 * <p>This constructor is public to permit tools that require a JavaBean instance 480 * to operate.</p> 481 */ 482 public RandomStringUtils() { 483 } 484 485 }