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 */ 017 package org.apache.commons.lang3; 018 019 import 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 * 032 * <p>#ThreadSafe#</p> 033 * @since 1.0 034 * @version $Id: RandomStringUtils.java 1199894 2011-11-09 17:53:59Z ggregory $ 035 */ 036 public class RandomStringUtils { 037 038 /** 039 * <p>Random object used by random method. This has to be not local 040 * to the random method so as to not return the same value in the 041 * same millisecond.</p> 042 */ 043 private static final Random RANDOM = new Random(); 044 045 /** 046 * <p>{@code RandomStringUtils} instances should NOT be constructed in 047 * standard programming. Instead, the class should be used as 048 * {@code RandomStringUtils.random(5);}.</p> 049 * 050 * <p>This constructor is public to permit tools that require a JavaBean instance 051 * to operate.</p> 052 */ 053 public RandomStringUtils() { 054 super(); 055 } 056 057 // Random 058 //----------------------------------------------------------------------- 059 /** 060 * <p>Creates a random string whose length is the number of characters 061 * specified.</p> 062 * 063 * <p>Characters will be chosen from the set of all characters.</p> 064 * 065 * @param count the length of random string to create 066 * @return the random string 067 */ 068 public static String random(int count) { 069 return random(count, false, false); 070 } 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 characters whose 077 * ASCII value is between {@code 32} and {@code 126} (inclusive).</p> 078 * 079 * @param count the length of random string to create 080 * @return the random string 081 */ 082 public static String randomAscii(int count) { 083 return random(count, 32, 127, false, false); 084 } 085 086 /** 087 * <p>Creates a random string whose length is the number of characters 088 * specified.</p> 089 * 090 * <p>Characters will be chosen from the set of alphabetic 091 * characters.</p> 092 * 093 * @param count the length of random string to create 094 * @return the random string 095 */ 096 public static String randomAlphabetic(int count) { 097 return random(count, true, false); 098 } 099 100 /** 101 * <p>Creates a random string whose length is the number of characters 102 * specified.</p> 103 * 104 * <p>Characters will be chosen from the set of alpha-numeric 105 * characters.</p> 106 * 107 * @param count the length of random string to create 108 * @return the random string 109 */ 110 public static String randomAlphanumeric(int count) { 111 return random(count, true, true); 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 numeric 119 * characters.</p> 120 * 121 * @param count the length of random string to create 122 * @return the random string 123 */ 124 public static String randomNumeric(int count) { 125 return random(count, false, true); 126 } 127 128 /** 129 * <p>Creates a random string whose length is the number of characters 130 * specified.</p> 131 * 132 * <p>Characters will be chosen from the set of alpha-numeric 133 * characters as indicated by the arguments.</p> 134 * 135 * @param count the length of random string to create 136 * @param letters if {@code true}, generated string will include 137 * alphabetic characters 138 * @param numbers if {@code true}, generated string will include 139 * numeric characters 140 * @return the random string 141 */ 142 public static String random(int count, boolean letters, boolean numbers) { 143 return random(count, 0, 0, letters, numbers); 144 } 145 146 /** 147 * <p>Creates a random string whose length is the number of characters 148 * specified.</p> 149 * 150 * <p>Characters will be chosen from the set of alpha-numeric 151 * characters as indicated by the arguments.</p> 152 * 153 * @param count the length of random string to create 154 * @param start the position in set of chars to start at 155 * @param end the position in set of chars to end before 156 * @param letters if {@code true}, generated string will include 157 * alphabetic characters 158 * @param numbers if {@code true}, generated string will include 159 * numeric characters 160 * @return the random string 161 */ 162 public static String random(int count, int start, int end, boolean letters, boolean numbers) { 163 return random(count, start, end, letters, numbers, null, RANDOM); 164 } 165 166 /** 167 * <p>Creates a random string based on a variety of options, using 168 * default source of randomness.</p> 169 * 170 * <p>This method has exactly the same semantics as 171 * {@link #random(int,int,int,boolean,boolean,char[],Random)}, but 172 * instead of using an externally supplied source of randomness, it uses 173 * the internal static {@link Random} instance.</p> 174 * 175 * @param count the length of random string to create 176 * @param start the position in set of chars to start at 177 * @param end the position in set of chars to end before 178 * @param letters only allow letters? 179 * @param numbers only allow numbers? 180 * @param chars the set of chars to choose randoms from. 181 * If {@code null}, then it will use the set of all chars. 182 * @return the random string 183 * @throws ArrayIndexOutOfBoundsException if there are not 184 * {@code (end - start) + 1} characters in the set array. 185 */ 186 public static String random(int count, int start, int end, boolean letters, boolean numbers, char... chars) { 187 return random(count, start, end, letters, numbers, chars, RANDOM); 188 } 189 190 /** 191 * <p>Creates a random string based on a variety of options, using 192 * supplied source of randomness.</p> 193 * 194 * <p>If start and end are both {@code 0}, start and end are set 195 * to {@code ' '} and {@code 'z'}, the ASCII printable 196 * characters, will be used, unless letters and numbers are both 197 * {@code false}, in which case, start and end are set to 198 * {@code 0} and {@code Integer.MAX_VALUE}. 199 * 200 * <p>If set is not {@code null}, characters between start and 201 * end are chosen.</p> 202 * 203 * <p>This method accepts a user-supplied {@link Random} 204 * instance to use as a source of randomness. By seeding a single 205 * {@link Random} instance with a fixed seed and using it for each call, 206 * the same random sequence of strings can be generated repeatedly 207 * and predictably.</p> 208 * 209 * @param count the length of random string to create 210 * @param start the position in set of chars to start at 211 * @param end the position in set of chars to end before 212 * @param letters only allow letters? 213 * @param numbers only allow numbers? 214 * @param chars the set of chars to choose randoms from. 215 * If {@code null}, then it will use the set of all chars. 216 * @param random a source of randomness. 217 * @return the random string 218 * @throws ArrayIndexOutOfBoundsException if there are not 219 * {@code (end - start) + 1} characters in the set array. 220 * @throws IllegalArgumentException if {@code count} < 0. 221 * @since 2.0 222 */ 223 public static String random(int count, int start, int end, boolean letters, boolean numbers, 224 char[] chars, Random random) { 225 if (count == 0) { 226 return ""; 227 } else if (count < 0) { 228 throw new IllegalArgumentException("Requested random string length " + count + " is less than 0."); 229 } 230 if (start == 0 && end == 0) { 231 end = 'z' + 1; 232 start = ' '; 233 if (!letters && !numbers) { 234 start = 0; 235 end = Integer.MAX_VALUE; 236 } 237 } 238 239 char[] buffer = new char[count]; 240 int gap = end - start; 241 242 while (count-- != 0) { 243 char ch; 244 if (chars == null) { 245 ch = (char) (random.nextInt(gap) + start); 246 } else { 247 ch = chars[random.nextInt(gap) + start]; 248 } 249 if (letters && Character.isLetter(ch) 250 || numbers && Character.isDigit(ch) 251 || !letters && !numbers) { 252 if(ch >= 56320 && ch <= 57343) { 253 if(count == 0) { 254 count++; 255 } else { 256 // low surrogate, insert high surrogate after putting it in 257 buffer[count] = ch; 258 count--; 259 buffer[count] = (char) (55296 + random.nextInt(128)); 260 } 261 } else if(ch >= 55296 && ch <= 56191) { 262 if(count == 0) { 263 count++; 264 } else { 265 // high surrogate, insert low surrogate before putting it in 266 buffer[count] = (char) (56320 + random.nextInt(128)); 267 count--; 268 buffer[count] = ch; 269 } 270 } else if(ch >= 56192 && ch <= 56319) { 271 // private high surrogate, no effing clue, so skip it 272 count++; 273 } else { 274 buffer[count] = ch; 275 } 276 } else { 277 count++; 278 } 279 } 280 return new String(buffer); 281 } 282 283 /** 284 * <p>Creates a random string whose length is the number of characters 285 * specified.</p> 286 * 287 * <p>Characters will be chosen from the set of characters 288 * specified.</p> 289 * 290 * @param count the length of random string to create 291 * @param chars the String containing the set of characters to use, 292 * may be null 293 * @return the random string 294 * @throws IllegalArgumentException if {@code count} < 0. 295 */ 296 public static String random(int count, String chars) { 297 if (chars == null) { 298 return random(count, 0, 0, false, false, null, RANDOM); 299 } 300 return random(count, chars.toCharArray()); 301 } 302 303 /** 304 * <p>Creates a random string whose length is the number of characters 305 * specified.</p> 306 * 307 * <p>Characters will be chosen from the set of characters specified.</p> 308 * 309 * @param count the length of random string to create 310 * @param chars the character array containing the set of characters to use, 311 * may be null 312 * @return the random string 313 * @throws IllegalArgumentException if {@code count} < 0. 314 */ 315 public static String random(int count, char... chars) { 316 if (chars == null) { 317 return random(count, 0, 0, false, false, null, RANDOM); 318 } 319 return random(count, 0, chars.length, false, false, chars, RANDOM); 320 } 321 322 }