Generate or validate a password Tag(s): Security


The generate() method produces a password with the following rules :
  • Given a minimum and maximum length
  • At least one lowercase letter
  • At least one uppercase letter
  • At least one digit
  • No special character

The validate() method validates a password against the same rules.

import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class PasswordTools {
   static String char_group = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
   static String digit_group = "123456789";

   /**
    * Generate a password with lower/uppercase, digit, min/max length
    * @param min length
    * @param max length
    * @return password
    */
   public static String generate(int min, int max) {
      if (min > max) {
            throw new IllegalArgumentException("min length > max length");
      }
      Random ran = new Random();
      int pwd_len = ran.nextInt(max + 1);
      while (pwd_len < min) {
         pwd_len = ran.nextInt(max + 1);
      }

      StringBuilder pwd = new StringBuilder();
      Random RNG = new Random();
      for (int i = 0; i < pwd_len ; i++) {
          int randomNum = RNG.nextInt(100);
          char c = ' ';
          // insert digit or letter
          if (randomNum % 4 == 0) {
              c = digit_group.charAt(randomNum  % digit_group.length());
          } else {
              c = char_group.charAt(randomNum  % char_group.length());
          }
          pwd.append(c);
      }
      return pwd.toString();
   }

   /**
    * Validate password, check for with lower/uppercase, digit, min/max length, no special character
    * @param pwd
    * @param min  min length
    * @param max  max length
    * @return  true/false
    */
   public static boolean validate(String pwd, int min, int max) {
      if (pwd == null) {
         return false;
      }

      if (min > max) {
         throw new IllegalArgumentException("min length > max length");
      }

      String regex = "^(?=.*[0-9])"        // at least one digit
                   + "(?=.*[a-z])"         // at least one letter lowercase
                   + "(?=.*[A-Z])"         // at least one letter uppercase
                   + "(?!.*[!@#&()[{}]:;',?/*~$^+=<>\" `|\\[\\]\\\\])."    // no special characters, no space
                   + "{" + min + "," + max + "}$";  // min length, max length
      Pattern p = Pattern.compile(regex);
      Matcher m = p.matcher(pwd);
      return m.matches();
   }

   public static void main(String args[]) {
      for (int i = 0; i < 10; i++) {
         System.out.println(PasswordTools.generate(6, 10));
      }
      /*
      dV4hQ7v
      j2g8P1Y32
      l781Y9NwQ
      D2wVbUz
      4pN2TLn
      N35JnE387
      8wbVxVzwBL
      dNbP4NzAr
      d2lk5k
      gIJUlsX3JM
      */
      System.out.println(PasswordTools.validate("7DMJd26", 6, 10));     // true
      System.out.println(PasswordTools.validate("Jd26", 6, 10));        // false, too short
      System.out.println(PasswordTools.validate("7DMJd26Jd26", 6, 10)); // false, too long
      System.out.println(PasswordTools.validate("7DMJ d26", 6, 10));    // false, space
      System.out.println(PasswordTools.validate("7DMJ@d26", 6, 10));    // false, special character
      System.out.println(PasswordTools.validate("7dmjd26", 6, 10));     // false, no uppercase
      System.out.println(PasswordTools.validate("7DMJD26", 6, 10));     // false, no lowercase
      System.out.println(PasswordTools.validate("DDMJddd", 6, 10));     // false, no digit
      System.out.println(PasswordTools.validate("7777777", 6, 10));     // false, no letter
   }
}

A simple way to generate using Apache Commons Lang is also provided. Add this to your POM to use it.

   <dependency>
       <groupId>org.apache.commons</groupId>
       <artifactId>commons-lang3</artifactId>
       <version>3.11</version>
   </dependency>

      for (int i = 0; i < 10; i++) {
        System.out.println
            (org.apache.commons.lang3.RandomStringUtils.randomAlphanumeric(6, 11)); // max length is exclusive so it's max length + 1
      }
      /*
      ON7LQQ8
      Grxjcl
      dKJHXFW9s
      pHwP05Y
      uKDIjP
      SzfYmhqP
      zW55VgJ2Z1
      bzAb3uLxr
      6NmT1Idli
      IkESyU6m
      */