• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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} &lt; 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} &lt; 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} &lt; 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