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