1

Possible Duplicate:
Creating a unique alphanumeric 10-character string

I need to generate unique random passwords.
So I thought of doing something like MD5(counter+a_random_string+timeInMills) but this has a 32 chars output.
I need a 8 chars passwords.
How can generate unique custom length human-readable passwords?

Update:
I generate N (less that 30) passwords each time and I need these N password be non-redundant. The need of uniqueness is not absolute. Also checking generated password for repeated value and re-generating it can cause an infinite loop

Community
  • 1
  • 1
Ariyan
  • 14,760
  • 31
  • 112
  • 175
  • What exactly do you mean by "unique" here? – NPE Dec 13 '12 at 18:37
  • @NPE: I mean it shouldn't happen that a password be generated twice. – Ariyan Dec 13 '12 at 18:38
  • You could take a substring of the first N chars of the MD5 sum... – maerics Dec 13 '12 at 18:38
  • @maerics: and it is unique? two MD5s can't have same first N chars? – Ariyan Dec 13 '12 at 18:39
  • They most certainly can have the same first N characters (they can even collide entirely) - you'll need to add another mechanism to ensure uniqueness. – maerics Dec 13 '12 at 18:40
  • Why are you limiting yourself to 8 characters? – Marvo Dec 13 '12 at 18:40
  • @maerics: So there isn't any custom length output (or less that 20) Message Digest Algorithm? – Ariyan Dec 13 '12 at 18:43
  • @Marvo: because of simplifying it for user. I don't want exact 8 chars just less that 20 is OK – Ariyan Dec 13 '12 at 18:44
  • There might be (I don't know of any) but remember that no MDA is collision free. You will have to ensure uniqueness some other way. – maerics Dec 13 '12 at 18:44
  • 3
    Even a 32 char MD5 hash isn't unique. As long as there are more passwords available than available MD5 hashes (and there are) there will always be colliding passwords. You should look up whether the password has already been used in order to be sure if you wish to do it this way. – Patrickdev Dec 13 '12 at 18:45
  • @Patrickdev: That was what I was thinking, but I was to lazy to explain. :P – Martijn Courteaux Dec 13 '12 at 18:46
  • 1
    why do you need passwords to be unique ?? – Amar Dec 13 '12 at 18:50
  • @Patrickdev: yes but I don't want to generate 16^32 passwords!! – Ariyan Dec 13 '12 at 18:51
  • @Amar: I generate N (less that 30) passwords each time and I need these N be non-redundant! and the uniqueness need is not absolute. but checking generated password for repeated value and re-generating it can cause an infinite loop – Ariyan Dec 13 '12 at 18:54
  • 2
    in that case see if this helps : http://stackoverflow.com/questions/467444/creating-a-unique-alphanumeric-10-character-string – Amar Dec 13 '12 at 19:02

6 Answers6

2

Here's an idea: use the java.util.UUID class.

The UUID class provides a static factory method to generate a pseudo-randomly generated UUID.

You can convert the UUID to a String.

Don't forget that if you want to guarantee uniqueness, you cannot truncate/substring the UUID's value:

Article on MSDN: GUIDs are globally unique, but substrings of GUIDs aren't.

Philip Tenn
  • 6,003
  • 8
  • 48
  • 85
2

Assuming an alphabet of upper/lower, number and 32 special characters (98 total), there are 988 possibilities or about 8.5x1015. If you want "unique" random passwords in the sense that you will not generate the same password twice without first having exhausted all possibilities, there are only two options:

  1. Generate a password at random. Keep track of all previously generated passwords, and if a collision occurs, try again... lather, rinse, repeat.
  2. Use a cyclic pseudo-random number generator, i.e. one that is guaranteed to select values that look random but does not repeat until all values have been used.

The second option is less secure, because if someone determines the algorithm then they can predict the next password (and the entire sequence) given one password.

Jim Garrison
  • 85,615
  • 20
  • 155
  • 190
1

The brute-force way to guarantee uniqueness of randomly generated strings would be to store all of them and regenerate on collision:

protected Collection<String> generatedPasswords = new HashSet<String>();
public String generatePassword(int length) {
  String password = null;
  do {
    StringBuilder buf = new StringBuilder();
    // Append "length" random password characters to "buf".
    password = buf.toString();
  } while (this.generatedPasswords.contains(password));
  return password;
}

However, if you're just trying to generate "reasonably" random passwords for end-users, and you're okay with the occasional (quite rare) collision then you could simply take the first N characters of your MD5 scheme.

maerics
  • 151,642
  • 46
  • 269
  • 291
  • This can cause an infinite loop. – Ariyan Dec 13 '12 at 18:57
  • @4r1y4n: yes, if/when you exhaust the entire space for a given length then this routine will cause an infinite loop; however, that condition can be checked. – maerics Dec 13 '12 at 19:06
1

I have created one random string/password generator program for me, hope this will work for you also.

public class RandomStringGenerator{

    private static int randomStringLength = 25 ;
    private static boolean allowSpecialCharacters = true ;
    private static String specialCharacters = "!@$%*-_+:";
    private static boolean allowDuplicates = false ;

    private static boolean isAlphanum = false;
    private static boolean isNumeric = false;
    private static boolean isAlpha = false;
    private static final String alphabet = "abcdefghijklmnopqrstuvwxyz";
    private static boolean mixCase = false;
    private static final String capAlpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    private static final String num = "0123456789";

    public static String getRandomString() {
        String returnVal = "";
        int specialCharactersCount = 0;
        int maxspecialCharacters = randomStringLength/4;

        try {
            StringBuffer values = buildList();
            for (int inx = 0; inx < randomStringLength; inx++) {
                int selChar = (int) (Math.random() * (values.length() - 1));
                if (allowSpecialCharacters)
                {
                    if (specialCharacters.indexOf("" + values.charAt(selChar)) > -1)
                    {
                        specialCharactersCount ++;
                        if (specialCharactersCount > maxspecialCharacters)
                        {
                            while (specialCharacters.indexOf("" + values.charAt(selChar)) != -1)
                            {
                                selChar = (int) (Math.random() * (values.length() - 1));
                            }
                        }
                    }
                }
                returnVal += values.charAt(selChar);
                if (!allowDuplicates) {
                    values.deleteCharAt(selChar);
                }
            }
        } catch (Exception e) {
            returnVal = "Error While Processing Values";
        }
        return returnVal;
    }

    private static StringBuffer buildList() {
        StringBuffer list = new StringBuffer(0);
        if (isNumeric || isAlphanum) {
            list.append(num);
        }
        if (isAlpha || isAlphanum) {
            list.append(alphabet);
            if (mixCase) {
                list.append(capAlpha);
            }
        }
        if (allowSpecialCharacters)
        {
            list.append(specialCharacters);
        }
        int currLen = list.length();
        String returnVal = "";
        for (int inx = 0; inx < currLen; inx++) {
            int selChar = (int) (Math.random() * (list.length() - 1));
            returnVal += list.charAt(selChar);
            list.deleteCharAt(selChar);
        }
        list = new StringBuffer(returnVal);
        return list;
    }   

}
Bhavik Ambani
  • 6,557
  • 14
  • 55
  • 86
0

Create a char array and fill it with random letters.

Random r = new Random();
char[] pass = new char[8];
for (int i = 0; i < pass.length; ++i)
{
    pass[i] = r.nextInt(26) + 'a';
}
String passStr = new String(pass);
Martijn Courteaux
  • 67,591
  • 47
  • 198
  • 287
0

You generate the random string using any simple algorithm (for example, see the solution to this : How do I create a random alpha-numeric string in C++?). Then what you can do is keep a Set (or any other data-structure which can ensure uniqueness) and keep inserting these random strings into it, once it reaches your required limit, you can just return the Set. Since you have a very small number of strings required(~50), chances of collision are also very very small, so it should be pretty efficient.

Community
  • 1
  • 1
Amar
  • 11,930
  • 5
  • 50
  • 73