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