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