How can I create a password?

23,778

Solution 1

RandomStringUtils from Apache Commons Lang provide some methods to generate a randomized String, that can be used as password.


Here are some examples of 8-characters passwords creation:

// Passwords with only alphabetic characters.
for (int i = 0; i < 8; i++) {
    System.out.println(RandomStringUtils.randomAlphabetic(8));
}
System.out.println("--------");
// Passwords with alphabetic and numeric characters.
for (int i = 0; i < 8; i++) {
    System.out.println(RandomStringUtils.randomAlphanumeric(8));
}

which creates the following result:

zXHzaLdG
oDtlFDdf
bqPbXVfq
tzQUWuxU
qBHBRKQP
uBLwSvnt
gzBcTnIm
yTUgXlCc
--------
khDzEFD2
cHz1p6yJ
3loXcBau
F6NJAQr7
PyfN079I
8tJye7bu
phfwpY6y
62q27YRt

Of course, you have also methods that may restrict the set of characters allowed for the password generation:

for (int i = 0; i < 8; i++) {
    System.out.println(RandomStringUtils.random(8, "abcDEF123"));
}

will create only passwords with the characters a, b, c, D, E, F, 1, 2 or 3:

D13DD1Eb
cac1Dac2
FE1bD2DE
2ab3Fb3D
213cFEFD
3c2FEDDF
FDbFcc1E
b2cD1c11

Solution 2

When using Apache's RandomStringUtils for security reasons (i.e. passwords), it's very important to combine the use of a SecureRandom source:

RandomStringUtils.random(6, 0, 0, true, true, null, new SecureRandom());

Solution 3

Use SecureRandom, it provides a more random passwords.

You can create a single password using something like this (note: untested code).

// put here all characters that are allowed in password
char[] allowedCharacters = {'a','b','c','1','2','3','4'};

SecureRandom random = new SecureRandom();
StringBuffer password = new StringBuffer();

for(int i = 0; i < PASSWORD_LENGTH; i++) {
    password.append(allowedCharacters[ random.nextInt(allowedCharacters.length) ]);
}

Note that this does not guarantee that the every password will have both digits and characters.

Solution 4

Here's one that I wrote a while back:

package com.stackoverflow.does.my.code.for.me;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.List;

public class PasswordUtil {

    /** Minimum password length = 6 */
    public static final int MIN_PASSWORD_LENGTH = 6;
    /** Maximum password length = 8 */
    public static final int MAX_PASSWORD_LENGTH = 8;

    /** Uppercase characters A-Z */
    public static final char[] UPPERS = new char[26];
    /** Lowercase characters a-z */
    public static final char[] LOWERS = new char[26];
    /**
     * Printable non-alphanumeric characters, excluding space.
     */
    public static final char[] SPECIALS = new char[32];
    public static final char[] DIGITS = new char[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

    static {
        // Static initializer block for populating arrays
        int U = 'A';
        int l = 'a';
        int d = '0';
        for (int i = 0; i < 26; i++) {
            UPPERS[i] = (char) (U + i);
            LOWERS[i] = (char) (l + i);
            if (i < 10) {
                DIGITS[i] = (char) (d + i);
            }
        }
        int p = 0;
        for (int s = 33; s < 127; s++) {
            char specialChar = (char) 32;

            if (s >= 'a' && s <= 'z')
                s = 'z' + 1; // jump over 'a' to 'z'
            else if (s >= 'A' && s <= 'Z')
                s = 'Z' + 1; // jump over 'A' to 'Z'
            else if (s >= '0' && s <= '9')
                s = '9' + 1; // jump over '0' to '9'

            specialChar = (char) s;
            SPECIALS[p] = specialChar;
            p++;
        }
    }

    public String generatePassword() {
        List<char[]> activeSets = new ArrayList<char[]>(4);
        List<char[]> inactiveSets = new ArrayList<char[]>(4);

        activeSets.add(UPPERS);
        activeSets.add(LOWERS);
        activeSets.add(SPECIALS);
        activeSets.add(DIGITS);

        SecureRandom random = new SecureRandom();

        int passwordLength = 5 + random.nextInt(3);
        StringBuffer password = new StringBuffer(passwordLength + 1);

        for (int p = 0; p <= passwordLength; p++) {
            char[] randomSet = null;
            if (activeSets.size() > 1) {
                int rSet = random.nextInt(activeSets.size());
                randomSet = activeSets.get(rSet);
                inactiveSets.add(randomSet);
                activeSets.remove(rSet);
            } else {
                randomSet = activeSets.get(0);
                inactiveSets.add(randomSet);
                activeSets.clear();
                activeSets.addAll(inactiveSets);
                inactiveSets.clear();
            }
            int rChar = random.nextInt(randomSet.length);
            char randomChar = randomSet[rChar];
            password.append(randomChar);
        }

        return password.toString();
    }
}

Solution 5

This is also a nice one:

String password = Integer.toString((int) (Math.random() * Integer.MAX_VALUE), 36);

It however does not guarantee that the password always contains both digits and letters, but most of the aforementioned suggestions also doesn't do that.

Share:
23,778
Johanna
Author by

Johanna

Updated on July 09, 2022

Comments

  • Johanna
    Johanna almost 2 years

    I want to give maybe a million password to some users that should be like:

    1. It must have at least 6 characters
    2. It must have digits and also letters

    Should I use Random here? How?

  • Sylar
    Sylar over 14 years
    SecureRandom returns numbers, but she asked for numbers and letters.
  • Juha Syrjälä
    Juha Syrjälä over 14 years
    This initializes random number generator inside loop, using current time. The password will not be very random. Also generated password may contain unprintable characters.
  • badbod99
    badbod99 over 14 years
    This code is referencing a character array by the returned integer value, so it does indeed return characters and numbers!
  • jk.
    jk. over 14 years
    this doesn't guarantee digits and letters in the password
  • skaffman
    skaffman over 14 years
    +1 the randomAlphabetic and randomAlphaNumeric are good for this, unless you want truly cryptographically random passwords.
  • Zelleriation
    Zelleriation over 14 years
    @jk: You are right. Then the password should be checked at the end of the process, and if it contains only letters or only digits, it can be either discarded and and the process started over, or a few characters of the missing group could be added manually. Anyway this should happen rarely.
  • Suraj Chandran
    Suraj Chandran over 14 years
    @juha...thats definitely right, maybe i was half asleep while asnwering this...i will update the answer :)
  • mhaller
    mhaller over 14 years
    can't stop to giggle whenever i read s.th. like "more random" :-}
  • Juha Syrjälä
    Juha Syrjälä over 14 years
    You are using the same random number to decide whether to use digits and characters and as a index to digit_group/char_group arrays. That is bit suspect. Also you should use much larger parameter to second RND.nextInt() call, something like MAX_INT, otherwise distribution of passwords may be skewed.
  • Visruth
    Visruth almost 11 years
    RandomStringUtils is broken, can you provide the correct link.
  • isaranchuk
    isaranchuk over 8 years
    RandomStringUtils is not well suited for password generation as it is based on standard Random, but not on SecureRandom
  • isaranchuk
    isaranchuk over 8 years
    Unless you manually specify secure random generator, see RandomStringUtils.random
  • Tobb
    Tobb almost 8 years
    This answer is a bit dangerous, since java.util.Random is being used by default (which is stated by others). java.util.Random is cracked, so if this is used for generating new passwords/tokens for password reset, there is a chance that an attacker might predict the next password/token and start stealing accounts. -1 due to this.