Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Algorithm to generate random string with harsh restrictions - Java

I'm trying to make a program to generate a random account name for the user. The user will hit a button and it will copy the account name to his clipboard. The GUI part of it is working but I just can't think of the best way to handle random generation of a String.

Allowed characters in the username: A-Z a-z _

No numbers, no other symbols, and no two of the same character in a row can occur.

Must be of length six.

My idea:

create an array of characters:

[ _, a, b, c, d ... etc ]

Generate a random integer between 0 and array.length - 1
 and pick the letter in that slot.

Check the last character to be added into the output String, 
and if it's the same as the one we just picked, pick again.

Otherwise, add it to the end of our String.

Stop if the String length is of length six.

Is there a better way? Perhaps with regex? I have a feeling the way I'm thinking of doing it here is really bad.

like image 490
Hatefiend Avatar asked Oct 18 '22 18:10

Hatefiend


1 Answers

I don't see anything wrong with your proposed algorithm (except you need to handle the first character you add without checking if you've already added it). You might also extract it to a static method and use a Random like,

static Random rand = new Random();

static String getPassword(String alphabet, int len) {
  StringBuilder sb = new StringBuilder(len);
  while (sb.length() < len) {
    char ch = alphabet.charAt(rand.nextInt(alphabet.length()));
    if (sb.length() > 0) {
      if (sb.charAt(sb.length() - 1) != ch) {
        sb.append(ch);
      }
    } else {
      sb.append(ch);
    }
  }
  return sb.toString();
}

Then you could call it with something like,

public static void main(String[] args) {
  StringBuilder alphabet = new StringBuilder();
  for (char ch = 'a'; ch <= 'z'; ch++) {
    alphabet.append(ch);
  }
  alphabet.append(alphabet.toString().toUpperCase()).append('_');
  String pass = getPassword(alphabet.toString(), 6);
  System.out.println(pass);
}
like image 76
Elliott Frisch Avatar answered Oct 21 '22 16:10

Elliott Frisch