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 * http://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.util.Random; 020 021/** 022 * <p>Generates random {@code String}s.</p> 023 * 024 * <p><b>Caveat: Instances of {@link Random}, upon which the implementation of this 025 * class relies, are not cryptographically secure.</b></p> 026 * 027 * <p>RandomStringUtils is intended for simple use cases. For more advanced 028 * use cases consider using Apache Commons Text's 029 * <a href="https://commons.apache.org/proper/commons-text/javadocs/api-release/org/apache/commons/text/RandomStringGenerator.html"> 030 * RandomStringGenerator</a> instead.</p> 031 * 032 * <p>The Apache Commons project provides 033 * <a href="https://commons.apache.org/rng">Commons RNG</a> dedicated to pseudo-random number generation, that may be 034 * a better choice for applications with more stringent requirements 035 * (performance and/or correctness).</p> 036 * 037 * <p>Note that <em>private high surrogate</em> characters are ignored. 038 * These are Unicode characters that fall between the values 56192 (db80) 039 * and 56319 (dbff) as we don't know how to handle them. 040 * High and low surrogates are correctly dealt with - that is if a 041 * high surrogate is randomly chosen, 55296 (d800) to 56191 (db7f) 042 * then it is followed by a low surrogate. If a low surrogate is chosen, 043 * 56320 (dc00) to 57343 (dfff) then it is placed after a randomly 044 * chosen high surrogate.</p> 045 * 046 * <p>#ThreadSafe#</p> 047 * @since 1.0 048 */ 049public class RandomStringUtils { 050 051 /** 052 * <p>Random object used by random method. This has to be not local 053 * to the random method so as to not return the same value in the 054 * same millisecond.</p> 055 */ 056 private static final Random RANDOM = new Random(); 057 058 /** 059 * <p>{@code RandomStringUtils} instances should NOT be constructed in 060 * standard programming. Instead, the class should be used as 061 * {@code RandomStringUtils.random(5);}.</p> 062 * 063 * <p>This constructor is public to permit tools that require a JavaBean instance 064 * to operate.</p> 065 */ 066 public RandomStringUtils() { 067 super(); 068 } 069 070 // Random 071 //----------------------------------------------------------------------- 072 /** 073 * <p>Creates a random string whose length is the number of characters 074 * specified.</p> 075 * 076 * <p>Characters will be chosen from the set of all characters.</p> 077 * 078 * @param count the length of random string to create 079 * @return the random string 080 */ 081 public static String random(final int count) { 082 return random(count, false, false); 083 } 084 085 /** 086 * <p>Creates a random string whose length is the number of characters 087 * specified.</p> 088 * 089 * <p>Characters will be chosen from the set of characters whose 090 * ASCII value is between {@code 32} and {@code 126} (inclusive).</p> 091 * 092 * @param count the length of random string to create 093 * @return the random string 094 */ 095 public static String randomAscii(final int count) { 096 return random(count, 32, 127, false, false); 097 } 098 099 /** 100 * <p>Creates a random string whose length is between the inclusive minimum and 101 * the exclusive maximum.</p> 102 * 103 * <p>Characters will be chosen from the set of characters whose 104 * ASCII value is between {@code 32} and {@code 126} (inclusive).</p> 105 * 106 * @param minLengthInclusive the inclusive minimum length of the string to generate 107 * @param maxLengthExclusive the exclusive maximum length of the string to generate 108 * @return the random string 109 * @since 3.5 110 */ 111 public static String randomAscii(final int minLengthInclusive, final int maxLengthExclusive) { 112 return randomAscii(RandomUtils.nextInt(minLengthInclusive, maxLengthExclusive)); 113 } 114 115 /** 116 * <p>Creates a random string whose length is the number of characters 117 * specified.</p> 118 * 119 * <p>Characters will be chosen from the set of Latin alphabetic 120 * characters (a-z, A-Z).</p> 121 * 122 * @param count the length of random string to create 123 * @return the random string 124 */ 125 public static String randomAlphabetic(final int count) { 126 return random(count, true, false); 127 } 128 129 /** 130 * <p>Creates a random string whose length is between the inclusive minimum and 131 * the exclusive maximum.</p> 132 * 133 * <p>Characters will be chosen from the set of Latin alphabetic characters (a-z, A-Z).</p> 134 * 135 * @param minLengthInclusive the inclusive minimum length of the string to generate 136 * @param maxLengthExclusive the exclusive maximum length of the string to generate 137 * @return the random string 138 * @since 3.5 139 */ 140 public static String randomAlphabetic(final int minLengthInclusive, final int maxLengthExclusive) { 141 return randomAlphabetic(RandomUtils.nextInt(minLengthInclusive, maxLengthExclusive)); 142 } 143 144 /** 145 * <p>Creates a random string whose length is the number of characters 146 * specified.</p> 147 * 148 * <p>Characters will be chosen from the set of Latin alphabetic 149 * characters (a-z, A-Z) and the digits 0-9.</p> 150 * 151 * @param count the length of random string to create 152 * @return the random string 153 */ 154 public static String randomAlphanumeric(final int count) { 155 return random(count, true, true); 156 } 157 158 /** 159 * <p>Creates a random string whose length is between the inclusive minimum and 160 * the exclusive maximum.</p> 161 * 162 * <p>Characters will be chosen from the set of Latin alphabetic 163 * characters (a-z, A-Z) and the digits 0-9.</p> 164 * 165 * @param minLengthInclusive the inclusive minimum length of the string to generate 166 * @param maxLengthExclusive the exclusive maximum length of the string to generate 167 * @return the random string 168 * @since 3.5 169 */ 170 public static String randomAlphanumeric(final int minLengthInclusive, final int maxLengthExclusive) { 171 return randomAlphanumeric(RandomUtils.nextInt(minLengthInclusive, maxLengthExclusive)); 172 } 173 174 /** 175 * <p>Creates a random string whose length is the number of characters specified.</p> 176 * 177 * <p>Characters will be chosen from the set of characters which match the POSIX [:graph:] 178 * regular expression character class. This class contains all visible ASCII characters 179 * (i.e. anything except spaces and control characters).</p> 180 * 181 * @param count the length of random string to create 182 * @return the random string 183 * @since 3.5 184 */ 185 public static String randomGraph(final int count) { 186 return random(count, 33, 126, false, false); 187 } 188 189 /** 190 * <p>Creates a random string whose length is between the inclusive minimum and 191 * the exclusive maximum.</p> 192 * 193 * <p>Characters will be chosen from the set of \p{Graph} characters.</p> 194 * 195 * @param minLengthInclusive the inclusive minimum length of the string to generate 196 * @param maxLengthExclusive the exclusive maximum length of the string to generate 197 * @return the random string 198 * @since 3.5 199 */ 200 public static String randomGraph(final int minLengthInclusive, final int maxLengthExclusive) { 201 return randomGraph(RandomUtils.nextInt(minLengthInclusive, maxLengthExclusive)); 202 } 203 204 /** 205 * <p>Creates a random string whose length is the number of characters 206 * specified.</p> 207 * 208 * <p>Characters will be chosen from the set of numeric 209 * characters.</p> 210 * 211 * @param count the length of random string to create 212 * @return the random string 213 */ 214 public static String randomNumeric(final int count) { 215 return random(count, false, true); 216 } 217 218 /** 219 * <p>Creates a random string whose length is between the inclusive minimum and 220 * the exclusive maximum.</p> 221 * 222 * <p>Characters will be chosen from the set of \p{Digit} characters.</p> 223 * 224 * @param minLengthInclusive the inclusive minimum length of the string to generate 225 * @param maxLengthExclusive the exclusive maximum length of the string to generate 226 * @return the random string 227 * @since 3.5 228 */ 229 public static String randomNumeric(final int minLengthInclusive, final int maxLengthExclusive) { 230 return randomNumeric(RandomUtils.nextInt(minLengthInclusive, maxLengthExclusive)); 231 } 232 233 /** 234 * <p>Creates a random string whose length is the number of characters specified.</p> 235 * 236 * <p>Characters will be chosen from the set of characters which match the POSIX [:print:] 237 * regular expression character class. This class includes all visible ASCII characters and spaces 238 * (i.e. anything except control characters).</p> 239 * 240 * @param count the length of random string to create 241 * @return the random string 242 * @since 3.5 243 */ 244 public static String randomPrint(final int count) { 245 return random(count, 32, 126, false, false); 246 } 247 248 /** 249 * <p>Creates a random string whose length is between the inclusive minimum and 250 * the exclusive maximum.</p> 251 * 252 * <p>Characters will be chosen from the set of \p{Print} characters.</p> 253 * 254 * @param minLengthInclusive the inclusive minimum length of the string to generate 255 * @param maxLengthExclusive the exclusive maximum length of the string to generate 256 * @return the random string 257 * @since 3.5 258 */ 259 public static String randomPrint(final int minLengthInclusive, final int maxLengthExclusive) { 260 return randomPrint(RandomUtils.nextInt(minLengthInclusive, maxLengthExclusive)); 261 } 262 263 /** 264 * <p>Creates a random string whose length is the number of characters 265 * specified.</p> 266 * 267 * <p>Characters will be chosen from the set of alpha-numeric 268 * characters as indicated by the arguments.</p> 269 * 270 * @param count the length of random string to create 271 * @param letters if {@code true}, generated string may include 272 * alphabetic characters 273 * @param numbers if {@code true}, generated string may include 274 * numeric characters 275 * @return the random string 276 */ 277 public static String random(final int count, final boolean letters, final boolean numbers) { 278 return random(count, 0, 0, letters, numbers); 279 } 280 281 /** 282 * <p>Creates a random string whose length is the number of characters 283 * specified.</p> 284 * 285 * <p>Characters will be chosen from the set of alpha-numeric 286 * characters as indicated by the arguments.</p> 287 * 288 * @param count the length of random string to create 289 * @param start the position in set of chars to start at 290 * @param end the position in set of chars to end before 291 * @param letters if {@code true}, generated string may include 292 * alphabetic characters 293 * @param numbers if {@code true}, generated string may include 294 * numeric characters 295 * @return the random string 296 */ 297 public static String random(final int count, final int start, final int end, final boolean letters, final boolean numbers) { 298 return random(count, start, end, letters, numbers, null, RANDOM); 299 } 300 301 /** 302 * <p>Creates a random string based on a variety of options, using 303 * default source of randomness.</p> 304 * 305 * <p>This method has exactly the same semantics as 306 * {@link #random(int,int,int,boolean,boolean,char[],Random)}, but 307 * instead of using an externally supplied source of randomness, it uses 308 * the internal static {@link Random} instance.</p> 309 * 310 * @param count the length of random string to create 311 * @param start the position in set of chars to start at 312 * @param end the position in set of chars to end before 313 * @param letters only allow letters? 314 * @param numbers only allow numbers? 315 * @param chars the set of chars to choose randoms from. 316 * If {@code null}, then it will use the set of all chars. 317 * @return the random string 318 * @throws ArrayIndexOutOfBoundsException if there are not 319 * {@code (end - start) + 1} characters in the set array. 320 */ 321 public static String random(final int count, final int start, final int end, final boolean letters, final boolean numbers, final char... chars) { 322 return random(count, start, end, letters, numbers, chars, RANDOM); 323 } 324 325 /** 326 * <p>Creates a random string based on a variety of options, using 327 * supplied source of randomness.</p> 328 * 329 * <p>If start and end are both {@code 0}, start and end are set 330 * to {@code ' '} and {@code 'z'}, the ASCII printable 331 * characters, will be used, unless letters and numbers are both 332 * {@code false}, in which case, start and end are set to 333 * {@code 0} and {@link Character#MAX_CODE_POINT}. 334 * 335 * <p>If set is not {@code null}, characters between start and 336 * end are chosen.</p> 337 * 338 * <p>This method accepts a user-supplied {@link Random} 339 * instance to use as a source of randomness. By seeding a single 340 * {@link Random} instance with a fixed seed and using it for each call, 341 * the same random sequence of strings can be generated repeatedly 342 * and predictably.</p> 343 * 344 * @param count the length of random string to create 345 * @param start the position in set of chars to start at (inclusive) 346 * @param end the position in set of chars to end before (exclusive) 347 * @param letters only allow letters? 348 * @param numbers only allow numbers? 349 * @param chars the set of chars to choose randoms from, must not be empty. 350 * If {@code null}, then it will use the set of all chars. 351 * @param random a source of randomness. 352 * @return the random string 353 * @throws ArrayIndexOutOfBoundsException if there are not 354 * {@code (end - start) + 1} characters in the set array. 355 * @throws IllegalArgumentException if {@code count} < 0 or the provided chars array is empty. 356 * @since 2.0 357 */ 358 public static String random(int count, int start, int end, final boolean letters, final boolean numbers, 359 final char[] chars, final Random random) { 360 if (count == 0) { 361 return StringUtils.EMPTY; 362 } else if (count < 0) { 363 throw new IllegalArgumentException("Requested random string length " + count + " is less than 0."); 364 } 365 if (chars != null && chars.length == 0) { 366 throw new IllegalArgumentException("The chars array must not be empty"); 367 } 368 369 if (start == 0 && end == 0) { 370 if (chars != null) { 371 end = chars.length; 372 } else { 373 if (!letters && !numbers) { 374 end = Character.MAX_CODE_POINT; 375 } else { 376 end = 'z' + 1; 377 start = ' '; 378 } 379 } 380 } else { 381 if (end <= start) { 382 throw new IllegalArgumentException("Parameter end (" + end + ") must be greater than start (" + start + ")"); 383 } 384 } 385 386 final int zero_digit_ascii = 48; 387 final int first_letter_ascii = 65; 388 389 if (chars == null && (numbers && end <= zero_digit_ascii 390 || letters && end <= first_letter_ascii)) { 391 throw new IllegalArgumentException("Parameter end (" + end + ") must be greater then (" + zero_digit_ascii + ") for generating digits " + 392 "or greater then (" + first_letter_ascii + ") for generating letters."); 393 } 394 395 final StringBuilder builder = new StringBuilder(count); 396 final int gap = end - start; 397 398 while (count-- != 0) { 399 int codePoint; 400 if (chars == null) { 401 codePoint = random.nextInt(gap) + start; 402 403 switch (Character.getType(codePoint)) { 404 case Character.UNASSIGNED: 405 case Character.PRIVATE_USE: 406 case Character.SURROGATE: 407 count++; 408 continue; 409 } 410 411 } else { 412 codePoint = chars[random.nextInt(gap) + start]; 413 } 414 415 final int numberOfChars = Character.charCount(codePoint); 416 if (count == 0 && numberOfChars > 1) { 417 count++; 418 continue; 419 } 420 421 if (letters && Character.isLetter(codePoint) 422 || numbers && Character.isDigit(codePoint) 423 || !letters && !numbers) { 424 builder.appendCodePoint(codePoint); 425 426 if (numberOfChars == 2) { 427 count--; 428 } 429 430 } else { 431 count++; 432 } 433 } 434 return builder.toString(); 435 } 436 437 438 /** 439 * <p>Creates a random string whose length is the number of characters 440 * specified.</p> 441 * 442 * <p>Characters will be chosen from the set of characters 443 * specified by the string, must not be empty. 444 * If null, the set of all characters is used.</p> 445 * 446 * @param count the length of random string to create 447 * @param chars the String containing the set of characters to use, 448 * may be null, but must not be empty 449 * @return the random string 450 * @throws IllegalArgumentException if {@code count} < 0 or the string is empty. 451 */ 452 public static String random(final int count, final String chars) { 453 if (chars == null) { 454 return random(count, 0, 0, false, false, null, RANDOM); 455 } 456 return random(count, chars.toCharArray()); 457 } 458 459 /** 460 * <p>Creates a random string whose length is the number of characters 461 * specified.</p> 462 * 463 * <p>Characters will be chosen from the set of characters specified.</p> 464 * 465 * @param count the length of random string to create 466 * @param chars the character array containing the set of characters to use, 467 * may be null 468 * @return the random string 469 * @throws IllegalArgumentException if {@code count} < 0. 470 */ 471 public static String random(final int count, final char... chars) { 472 if (chars == null) { 473 return random(count, 0, 0, false, false, null, RANDOM); 474 } 475 return random(count, 0, chars.length, false, false, chars, RANDOM); 476 } 477 478}