Generating a Random Password with Restrictions in Java

Almost in all our projects involving user information, there will be a requirement for the random generation of password by the application.

On Google search for the term ‘random password generation java’ you may come across various solutions like using java.security.SecureRandom, java.util.UUID, Apache Commons RandomStringUtils, some loop constructs etc. While all these solutions focus on generating a random alpha numeric string (including special characters) of specified length, whenever there are password restrictions in place (which is the case in almost all application requirements) like – atleast one capital letter, one digit, one special character etc, the above mentioned solutions may not work out of the box and you may need to tweak it to suit your needs.

In this example, we will see how to generate a random password with restrictions like minimum and maximum length, number of capital letters, number of digits and number of special characters.

Random Password Generator

Below is our class “RandomPasswordGenerator” with a static method “generatePswd” which takes 5 parameters – min length, max length, number of capital letters, number of digits and number of special characters.

package com.theopentutorials.utility;

import java.util.Random;

public class RandomPasswordGenerator {
	private static final String ALPHA_CAPS 	= "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
	private static final String ALPHA 	= "abcdefghijklmnopqrstuvwxyz";
	private static final String NUM 	= "0123456789";
	private static final String SPL_CHARS	= "!@#$%^&*_=+-/";

	public static char[] generatePswd(int minLen, int maxLen, int noOfCAPSAlpha, 
			int noOfDigits, int noOfSplChars) {
		if(minLen > maxLen)
			throw new IllegalArgumentException("Min. Length > Max. Length!");
		if( (noOfCAPSAlpha + noOfDigits + noOfSplChars) > minLen )
			throw new IllegalArgumentException
			("Min. Length should be atleast sum of (CAPS, DIGITS, SPL CHARS) Length!");
		Random rnd = new Random();
		int len = rnd.nextInt(maxLen - minLen + 1) + minLen;
		char[] pswd = new char[len];
		int index = 0;
		for (int i = 0; i < noOfCAPSAlpha; i++) {
			index = getNextIndex(rnd, len, pswd);
			pswd[index] = ALPHA_CAPS.charAt(rnd.nextInt(ALPHA_CAPS.length()));
		}
		for (int i = 0; i < noOfDigits; i++) {
			index = getNextIndex(rnd, len, pswd);
			pswd[index] = NUM.charAt(rnd.nextInt(NUM.length()));
		}
		for (int i = 0; i < noOfSplChars; i++) {
			index = getNextIndex(rnd, len, pswd);
			pswd[index] = SPL_CHARS.charAt(rnd.nextInt(SPL_CHARS.length()));
		}
		for(int i = 0; i < len; i++) {
			if(pswd[i] == 0) {
				pswd[i] = ALPHA.charAt(rnd.nextInt(ALPHA.length()));
			}
		}
		return pswd;
	}
	
	private static int getNextIndex(Random rnd, int len, char[] pswd) {
		int index = rnd.nextInt(len);
		while(pswd[index = rnd.nextInt(len)] != 0);
		return index;
	}
}

Output

Here is a test class for our “RandomPasswordGenerator” which generates 10 passwords with min length of 8 and max length of 12 along with 1 capital letter, digit and special character.

package com.theopentutorials.utility;

public class RandomPasswordGeneratorTest {

	public static void main(String[] args) {
		int noOfCAPSAlpha = 1;
		int noOfDigits = 1;
		int noOfSplChars = 1;
		int minLen = 8;
		int maxLen = 12;

		for (int i = 0; i < 10; i++) {
			char[] pswd = RandomPasswordGenerator.generatePswd(minLen, maxLen,
					noOfCAPSAlpha, noOfDigits, noOfSplChars);
			System.out.println("Len = " + pswd.length + ", " + new String(pswd));
		}
	}
}

Len = 9, fzrxz+1eZ
Len = 12, jgxbsH2o*gxu
Len = 10, voim9mnWy-
Len = 11, t8$olbjobjF
Len = 11, wsLiss7_ikd
Len = 12, r$6Hmnmfhinr
Len = 12, L6hlegg#aywd
Len = 11, id^4oTifqyv
Len = 12, e4stdzwgKu@h
Len = 9, x!qBxlpx5

Leave a Comment