title: Efficient non-repeating password generator in Java
body: <p>I have gone to this site many times and found answers to my questions but its finally time for me to post one of my own!  So the objective of a particular class in my software is to generate random passwords of fixed length, comprised of 'low' ASCII characters.  The main catch is that I do not want to generate the same password twice but always guarantee uniqueness.  Initially I used a <a href="http://docs.oracle.com/javase/6/docs/api/java/util/HashMap.html" rel="nofollow">HashMap</a> in order to hash each password I had generated so far and use as a check each time I created a new one before returning.  However, Java HashMap objects are limited in size and eventually the Map would become too saturated to maintain acceptable retrieval time.  The following is my latest crack at the problem:</p>
  
  <pre><code>package gen;
  
  import java.util.Set;
  
  import java.util.Random;
  
  import java.util.HashSet;
  
  public class Generator {
  
  Random r;
  int length;
  Set&lt;String&gt; seen;
  
  public Generator(int l){
      seen = new HashSet&lt;String&gt;();
      length = l;
      r = new Random();
      r.setSeed(System.currentTimeMillis());
  }
  
  public String generate(){   
      String retval = "";
      int i = 0;
      while(i&lt;length){
          int rand = r.nextInt(93)+33;
          if(rand!=96){
              retval+= (char)rand;
              i++;
          }
      }
      return retval;
  }
  
  public String generateNoRepeat(){
      String retval;
      int i;
      do{
          retval ="";
          i = 0;
          while(i&lt;length){
              int rand = r.nextInt(93)+33;
              if(rand!=96){
                  retval+= (char)rand;
                  i++;
              }
          }
      }while(!seen.add(retval));
      return retval;
  }
  }
  </code></pre>
  
  <p>Edit: Thanks so much for the Set suggestion. It makes my code so much cleaner now too!</p>
  
  <p>I may decide to just use the dumb generator method to fill up a <a href="http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/BlockingQueue.html" rel="nofollow">BlockingQueue</a> and just multithread it to death... </p>
  
  <p>Further clarification:  This is not meant to generate secure passwords.  It must simply guarantee that it will eventually generate all possible passwords and only once for a given length and character set.</p>
  
  <p>Note:</p>
  
  <p>I have taken everyone's insight and have come to the conclusion that sequentially generating the possible passwords and storing them to the disk is probably my best option.  Either that or simply allow duplicate passwords and supplement the inefficiency with multiple Generator threads.</p>