93

As the title suggest I need to create a random, 17 characters long, ID. Something like "AJB53JHS232ERO0H1". The order of letters and numbers is also random. I thought of creating an array with letters A-Z and a 'check' variable that randoms to 1-2. And in a loop;

Randomize 'check' to 1-2.
If (check == 1) then the character is a letter.
Pick a random index from the letters array.
else
Pick a random number.

But I feel like there is an easier way of doing this. Is there?

Ruchira Gayan Ranaweera
  • 34,993
  • 17
  • 75
  • 115
cbt
  • 1,271
  • 1
  • 11
  • 20
  • 2
    http://stackoverflow.com/questions/41107/how-to-generate-a-random-alpha-numeric-string – aquaraga Dec 12 '13 at 06:36
  • you can put your letters and digits into an array and then randomly choose elements from it until you reach your desired size. – wxyz Dec 12 '13 at 06:37

4 Answers4

137

Here you can use my method for generating Random String

protected String getSaltString() {
        String SALTCHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
        StringBuilder salt = new StringBuilder();
        Random rnd = new Random();
        while (salt.length() < 18) { // length of the random string.
            int index = (int) (rnd.nextFloat() * SALTCHARS.length());
            salt.append(SALTCHARS.charAt(index));
        }
        String saltStr = salt.toString();
        return saltStr;

    }

The above method from my bag using to generate a salt string for login purpose.

Suresh Atta
  • 120,458
  • 37
  • 198
  • 307
  • 1
    May I suggest to replace `StringBuffer` by a `StringBuilder`, no need to have a thread-safe impl. here –  Dec 12 '13 at 06:42
  • 11
    Or just create a `char[]` given that you know exactly how long it will be. No need to append anything. I'd also use `Random.nextInt` rather than calling `nextFloat` and multiplying it by the length. – Jon Skeet Dec 12 '13 at 06:44
  • 2
    Note that the average amount of numbers won't be the same as the amount of letters. – Martijn Courteaux Dec 12 '13 at 06:44
  • @RC. Yes. I'm using it in a servlet environment. So need it. Otherwise a StringBuilder – Suresh Atta Dec 12 '13 at 06:47
  • One thing to keep in mind if you use this is that, the Random class is sudo random and not a true random. Tried to use this to print 400 Strings to a file and found that it wasn't as random as I wanted. :( – SharpInnovativeTechnologies Dec 26 '18 at 01:46
  • @SharpIncTechAndProgramming have you tried it with SecureRandom ? Also to my knowledge (maybe I'm wrong) it would be better to provide the same instance of Random to all Strings generated. – Delark Feb 22 '21 at 13:28
118

RandomStringUtils from Apache commons-lang might help:

RandomStringUtils.randomAlphanumeric(17).toUpperCase()

2017 update: RandomStringUtils has been deprecated, you should now use RandomStringGenerator.

  • 3
    Consider updating the answer as Apache replaced it with `RandomStringGenerator` in commons-text. – Neria Nachum Aug 08 '17 at 08:23
  • 2
    You can also use `RandomStringUtils.random(length, useLetters, useNumbers)` where length is **int** while useLetters and useNumbers are **boolean** values. – Pratik Patel Sep 22 '18 at 11:42
  • 1
    Superb,Single line code,we require this type of codes. – Rajesh Om Nov 13 '18 at 07:41
  • 3
    @NeriaNachum where are you seeing that `RandomStringUtils` has been replaced/deprecated? I'm just seeing "RandomStringUtils is intended for simple use cases. For more advanced use cases consider using Apache Commons Text's RandomStringGenerator instead." [here](https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/RandomStringUtils.html) – wileyquixote May 29 '20 at 14:20
  • 1
    Using RandomStringGenerator (from apachae common) you can produce a random String of desired length. Following snippet will generate a String of length between 5 - 15 ( both inclusive) // char [][] pairs = {{'a','z'},{'A','Z'},{'0','9'}}; RandomStringGenerator randomStringGenerator = new RandomStringGenerator.Builder() .withinRange(pairs) .build(); String randomString = randomStringGenerator.generate(5, 15); // – Ajay Singh Jun 08 '22 at 10:28
19

Three steps to implement your function:

Step#1 You can specify a string, including the chars A-Z and 0-9.

Like.

 String candidateChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";

Step#2 Then if you would like to generate a random char from this candidate string. You can use

 candidateChars.charAt(random.nextInt(candidateChars.length()));

Step#3 At last, specify the length of random string to be generated (in your description, it is 17). Writer a for-loop and append the random chars generated in step#2 to StringBuilder object.

Based on this, here is an example public class RandomTest {

public static void main(String[] args) {

    System.out.println(generateRandomChars(
            "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890", 17));
}

/**
 * 
 * @param candidateChars
 *            the candidate chars
 * @param length
 *            the number of random chars to be generated
 * 
 * @return
 */
public static String generateRandomChars(String candidateChars, int length) {
    StringBuilder sb = new StringBuilder();
    Random random = new Random();
    for (int i = 0; i < length; i++) {
        sb.append(candidateChars.charAt(random.nextInt(candidateChars
                .length())));
    }

    return sb.toString();
}

}
Mengjun
  • 3,159
  • 1
  • 15
  • 21
8

You can easily do that with a for loop,

public static void main(String[] args) {
  String aToZ="ABCD.....1234"; // 36 letter.
  String randomStr=generateRandom(aToZ);

}

private static String generateRandom(String aToZ) {
    Random rand=new Random();
    StringBuilder res=new StringBuilder();
    for (int i = 0; i < 17; i++) {
       int randIndex=rand.nextInt(aToZ.length()); 
       res.append(aToZ.charAt(randIndex));            
    }
    return res.toString();
}
Masudul
  • 21,823
  • 5
  • 43
  • 58