In this article, I’ll show you how to generate a random password in Java. This Java generator can be used by a website when a user forgets their password. The app will generate a new password and email it to the user. This article will simply focus on the code for generating the random password in Java. The password is randomly generated and follows these security rules:
- at least 8 characters, max of 12
- at least one uppercase
- at least one lowercase
- at least one number
- at least one symbol @#$%=:?
Before we get into the coding of the Java implementation class, we will write a unit test. The unit test will verify that the generated password follows the security rules. In a previous post, I developed a regular expression to validate a given password. I will simply reuse that regular expression in our unit test.
[code]
@Test
public void generatePassword() {
// setup
String regex = "((?=.*\\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%=:\\?]).{8,12})";
// execute
String thePassword = PasswordUtils.generatePassword();
// assert
assertNotNull(thePassword);
assertTrue(thePassword.matches(regex));
}
[/code]
This test sets up the regular expression for password validation. Then we execute the method PasswordUtils.generatePassword(). Once the password is generated, then we verify this is a valid password using the regular expression.
Now let’s move on to the implementation code. We can start with a very basic implementation, that will of course fail our test. This is what we’re starting out with.
[code]
public static String generatePassword() {
return null;
}
[/code]
The test fails because we assert the password is not null. That is fine, since we’re following the TDD process of “write a failing test first”. Now, we need to provide the real implementation code. In the implementation, we need to follow the rules listed above. In brief, 8-12 characters, at least one upper, one lower, one digit and one symbol @#$%=:?. So in order to accomplish this, we’ll define the valid characters/digits for each rule.
Let’s walk thru the code to see how it works. The code starts with defining a constant for the maximum length of the password. We’ll also define a random generator that we use later.
[code]
public class PasswordUtils {
/**
* Minimum length for a decent password
*/
protected static final int MAX_LENGTH = 12;
/**
* The random number generator.
*/
private static java.util.Random r = new java.util.Random();
[/code]
Now, we’ll define the range of valid characters, numbers and symbols that we’ll use in the password. This is accomplished with the code below:
[code]
/**
* I, L and O are good to leave out as are numeric zero and one.
*/
private static final String DIGITS = "23456789";
private static final String LOCASE_CHARACTERS = "abcdefghjkmnpqrstuvwxyz";
private static final String UPCASE_CHARACTERS = "ABCDEFGHJKMNPQRSTUVWXYZ";
private static final String SYMBOLS = "@#$%=:?";
private static final String ALL = DIGITS + LOCASE_CHARACTERS + UPCASE_CHARACTERS + SYMBOLS;
private static final char[] upcaseArray = UPCASE_CHARACTERS.toCharArray();
private static final char[] locaseArray = LOCASE_CHARACTERS.toCharArray();
private static final char[] digitsArray = DIGITS.toCharArray();
private static final char[] symbolsArray = SYMBOLS.toCharArray();
private static final char[] allArray = ALL.toCharArray();
[/code]
If you have been in the IT industry for a while, you will know that certain characters do not make good password characters. Namely, the letters “I”, “L”, and “O”. They are easily confused with their number counterparts “1” and “0” so we’ll leave them out too.
Next we’ll cover the method implementation.
[code]
/**
* Generate a random password based on security rules
*
* – at least 8 characters, max of 12
* – at least one uppercase
* – at least one lowercase
* – at least one number
* – at least one symbol
*
* @return
*/
public static String generatePassword() {
StringBuilder sb = new StringBuilder();
// get at least one lowercase letter
sb.append(locaseArray[r.nextInt(locaseArray.length)]);
// get at least one uppercase letter
sb.append(upcaseArray[r.nextInt(upcaseArray.length)]);
// get at least one digit
sb.append(digitsArray[r.nextInt(digitsArray.length)]);
// get at least one symbol
sb.append(symbolsArray[r.nextInt(symbolsArray.length)]);
// fill in remaining with random letters
for (int i = 0; i < MAX_LENGTH – 4; i++) {
sb.append(allArray[r.nextInt(allArray.length)]);
}
return sb.toString();
}
[/code]
In this method, we’re building the password string using concatenation. In this case, we have the option of using StringBuffer or StringBuilder. I chose StringBuilder since it is unsynchronized and results in faster code. Now, it is just a matter of choosing a random character from each of the arrays and append it to the string. After we have the first 4 characters/digits taken care of then we fill the remaining characters with random characters from the allArray. At the end of the method, we return a string version of the password.
Here is the complete code for the class.
[code]
package com.luv2code.password.util;
/**
*
* @author Chad Darby, darby@luv2code.com
*/
public class PasswordUtils {
/**
* Minimum length for a decent password
*/
protected static final int MAX_LENGTH = 12;
/**
* The random number generator.
*/
private static java.util.Random r = new java.util.Random();
/**
* I, L and O are good to leave out as are numeric zero and one.
*/
private static final String DIGITS = "23456789";
private static final String LOCASE_CHARACTERS = "abcdefghjkmnpqrstuvwxyz";
private static final String UPCASE_CHARACTERS = "ABCDEFGHJKMNPQRSTUVWXYZ";
private static final String SYMBOLS = "@#$%=:?";
private static final String ALL = DIGITS + LOCASE_CHARACTERS + UPCASE_CHARACTERS + SYMBOLS;
private static final char[] upcaseArray = UPCASE_CHARACTERS.toCharArray();
private static final char[] locaseArray = LOCASE_CHARACTERS.toCharArray();
private static final char[] digitsArray = DIGITS.toCharArray();
private static final char[] symbolsArray = SYMBOLS.toCharArray();
private static final char[] allArray = ALL.toCharArray();
/**
* Generate a random password based on security rules
*
* – at least 8 characters, max of 12
* – at least one uppercase
* – at least one lowercase
* – at least one number
* – at least one symbol
*
* @return
*/
public static String generatePassword() {
StringBuilder sb = new StringBuilder();
// get at least one lowercase letter
sb.append(locaseArray[r.nextInt(locaseArray.length)]);
// get at least one uppercase letter
sb.append(upcaseArray[r.nextInt(upcaseArray.length)]);
// get at least one digit
sb.append(digitsArray[r.nextInt(digitsArray.length)]);
// get at least one symbol
sb.append(symbolsArray[r.nextInt(symbolsArray.length)]);
// fill in remaining with random letters
for (int i = 0; i < MAX_LENGTH – 4; i++) {
sb.append(allArray[r.nextInt(allArray.length)]);
}
return sb.toString();
}
public static void main(String[] args) {
// generate the password
String thePassword = PasswordUtils.generatePassword();
// now print it out
System.out.println("Generated password is: " + thePassword);
}
}
[/code]
Now that the code is complete, we can test it using our unit test. Based on the coding, the unit test passes with flying colors, green bar!
The source code is available here.
I hope that you have found this article useful. Enjoy!
Dear Chad,
At 1st thanks for this example but you have to add “main” class into code for running program as;
public static void main(String args[]){
System.out.println(“Generated random password : ” + generatePassword());
}
Thanks for best Courses 😉
Good catch Tolga! I’ve updated the blog post
And also it’s no need to use “PasswordUtil” class too, i think. Just add this code below into main class.
System.out.println(“Generated random password : ” + generatePassword());
yeah, I like to use the className.method in case someone wants to see how to call the code from outside the class. Since this is a utility class, the most common use case will be calling it from another class.
but good point though 🙂