2015-11-04 2 views
1

Я хотел бы создать генератор паролей, создающих пароль в соответствии с установленным пользователем ограничением. Ограничения есть:генерация случайного пароля с ограничением в java

  1. Минимальная длина пароля
  2. Максимальная длина пароля
  3. Минимальное письмо И Digit
  4. Минимальное письмо
  5. Минимальное Прописные письмо
  6. Минимальное строчных букв
  7. Минимальная Digit
  8. Максимальный повторяющийся символ

Я смотрю через Google, и большинство примеров кода не соответствует требуемому требованию. Так что я импровизировать код вроде этого:

private char[] GeneratePassword(int minLength, int maxLength, 
     int maxRepeatCharacter, int minLetterAndDigit, int minLetter, 
     int minLowerCaseLetter, int minUpperCaseLetter, int minDigit) { 

    final String LETTER = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; 
    final String UPPERCASE = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 
    final String LOWERCASE = "abcdefghijklmnopqrstuvwxyz"; 
    final String DIGIT = ""; 
    final String[] randomSelector = {LETTER,UPPERCASE,LOWERCASE,DIGIT}; 

    int len = getRandomNumber(minLength, maxLength); 
    char[] passwordGenerated = new char[len]; 
    char[] characterUsed = new char[len]; 
    int selection; 
    int letterAndDigitUsed = 0; 
    int letterUsed = 0; 
    int lowerCaseLetterUsed = 0; 
    int upperCaseLetterUsed = 0; 
    int digitUsed = 0; 
    int index = 0; 

    if (minLength > maxLength) { 
     // throw new IllegalArgumentException("Min.Length > Max.Length!"); 
    } 

    if (minLetter + minDigit > minLetterAndDigit) { 
     // throw new IllegalArgumentException("Error!"); 
    } 

    while (index != len) { 
     selection = getRandomNumber(0, randomSelector.length); 
     if (selection == 0) { 
      passwordGenerated[index] = LETTER.charAt(RandomUtils.nextInt(0, 
        LETTER.length())); 
      if (checkRepeatCharacter(passwordGenerated[index], 
        characterUsed, index, maxRepeatCharacter) == false) { 
       characterUsed[index] = passwordGenerated[index]; 
       index++; 
       letterUsed++; 
       letterAndDigitUsed++; 
       break; 
      } 
     } else if (selection == 1) { 
      passwordGenerated[index] = UPPERCASE.charAt(RandomUtils 
        .nextInt(0, UPPERCASE.length())); 
      if (checkRepeatCharacter(passwordGenerated[index], 
        characterUsed, index, maxRepeatCharacter) == false) { 
       characterUsed[index] = passwordGenerated[index]; 
       index++; 
       upperCaseLetterUsed++; 
       letterAndDigitUsed++; 
       break; 
      } 
     } else if (selection == 2) { 
      passwordGenerated[index] = LOWERCASE.charAt(RandomUtils 
        .nextInt(0, LOWERCASE.length())); 
      if (checkRepeatCharacter(passwordGenerated[index], 
        characterUsed, index, maxRepeatCharacter) == false) { 
       characterUsed[index] = passwordGenerated[index]; 
       index++; 
       lowerCaseLetterUsed++; 
       letterAndDigitUsed++; 
       break; 
      } 
     } else if (selection == 3) { 
      passwordGenerated[index] = DIGIT.charAt(RandomUtils.nextInt(0, 
        DIGIT.length())); 
      if (checkRepeatCharacter(passwordGenerated[index], 
        characterUsed, index, maxRepeatCharacter) == false) { 
       characterUsed[index] = passwordGenerated[index]; 
       index++; 
       digitUsed++; 
       letterAndDigitUsed++; 
       break; 
      } 
     } 
    } 

    return passwordGenerated; 
} 

private boolean checkRepeatCharacter(char passwordGenerated, 
     char[] passwordUsed, int index, int maxRepeatCharacter) { 
    int characterRepeated = 0; 
    for (int i = 0; i < index; i++) { 
     if (String.valueOf(passwordUsed[i]).equals(
       String.valueOf(passwordGenerated))) { 
      characterRepeated++; 
      if (characterRepeated == maxRepeatCharacter) { 
       return true; 
      } 
     } 
    } 
    return false; 
} 

private int getRandomNumber(int minLength, int maxLength) { 
    Random r = new Random(); 
    return r.nextInt(maxLength - minLength) + minLength; 
} 

Проблемы, что у меня есть, как обеспечить минимальное условие выполнено. В то же время я не хочу, чтобы мой пароль был сгенерирован, повторяя один и тот же тип символа.

  1. Пример: Если я кладу максимальную длину пароля до 10, и я хочу минимальную цифру 5. Я предпочитаю иметь 1jP2k3o4m9, а не 57812aJ9tP.

  2. 2-й пример: если я надену максимальную длину пароля на 5, и мне нужна минимальная строчная буква 3. Я предпочитаю иметь Pj9mn, а не jkl5V.

Как вы можете видеть, второй сгенерированный пароль сначала пытается заполнить минимальное требование, а затем сделать случайный выбор только для другого символьного типа. Это сделает пароль более уязвимым. Есть ли способ сделать этот алгоритм.

Ref: Generating a Random Password with Restrictions in Java

+0

'3' ** не является ** строчной буквы. –

+0

@ElliottFrisch, на какую часть вы имеете в виду? –

+0

* Я установил максимальную длину пароля на 5 и хочу минимальную строчную букву 3 * –

ответ

1

Я исправил свой код. Пока я тестировал, я отлично работаю по мере необходимости. Я оставляю этот код на всякий случай, если кому-то это понадобится в будущем.

private boolean checkRepeatCharacter(char randomCharacter, 
     ArrayList<Character> passwordUsed, int usedLength, 
     int maxRepeatCharacter) { 
    int characterRepeated = 0; 
    for (int i = 0; i < usedLength; i++) { 
     if (String.valueOf(passwordUsed.get(i)).equals(
       String.valueOf(randomCharacter))) { 
      characterRepeated++; 
      if (characterRepeated == maxRepeatCharacter) { 
       return false; 
      } 
     } 
    } 
    return true; 
} 

private boolean checkUsedIndex(int index, ArrayList<Integer> usedIndex) { 
    for (int i = 0; i < usedIndex.size(); i++) { 
     if (usedIndex.contains(index)) { 
      return false; 
     } 
    } 
    return true; 
} 

private int getRandomNumber(int minLength, int maxLength) { 
    Random r = new Random(); 
    return r.nextInt(maxLength - minLength) + minLength; 
} 

public String generatePassword(int minLength, int maxLength, 
     int maxRepeatCharacter, int minLetterAndDigit, int minLetter, 
     int minLowerCaseLetter, int minUpperCaseLetter, int minDigit, 
     int minSpecialCharacter, String specialCharacter) { 

    final String LOWERCASE = "abcdefghijklmnopqrstuvwxyz"; 
    final String UPPERCASE = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 
    final String DIGIT = ""; 
    StringBuilder ALL = new StringBuilder(); 
    ALL.append(LOWERCASE); 
    ALL.append(UPPERCASE); 
    ALL.append(DIGIT); 
    ALL.append(specialCharacter); 
    ALL.toString(); 

    char getRandom; 
    int length = 0; 
    StringBuilder passwordGenerated = new StringBuilder(); 
    ArrayList<Character> characterUsed = new ArrayList<Character>(); 
    ArrayList<Integer> indexUsed = new ArrayList<Integer>(); 

    int passwordLength = 0; 
    int lowerCaseLetterUsed = 0; 
    int upperCaseLetterUsed = 0; 
    int letterUsed = 0; 
    int digitUsed = 0; 
    int letterAndDigitUsed = 0; 
    int specialCharacterUsed = 0; 

    if (minLength > maxLength) { 
     throw new IllegalArgumentException("Min. Length > Max. Length!"); 
    } 

    if (minUpperCaseLetter + minLowerCaseLetter > minLetter) { 
     throw new RuntimeException(
       "mininimum Lower Case + Minimum Uppercase cannot exceed minLetter"); 
    } 
    if (minLetter + minDigit > minLetterAndDigit) { 
     throw new RuntimeException(
       "mininimum Letter + Minimum Digit cannot exceed minimum Letter And Digit"); 
    } 
    if (minLetter + minDigit + minSpecialCharacter > maxLength) { 
     throw new RuntimeException(
       "minimum Digit + minimum Letter + Minimum Special Character cannot excced maximum Length"); 
    } 

    while ((length < minLetter) && (length < minLetterAndDigit)) { 
     length = getRandomNumber(minLength, maxLength); 
    } 

    while (passwordLength != length) { 
     while (letterAndDigitUsed < minLetterAndDigit) { 
      while (letterUsed < minLetter) { 
       lowerCaseLetterUsed = 0; 
       for (int i = 0; lowerCaseLetterUsed < minLowerCaseLetter; i++) { 
        int index = getRandomNumber(0, length); 
        if (checkUsedIndex(index, indexUsed) == true) { 
         getRandom = LOWERCASE.charAt(getRandomNumber(0, 
           LOWERCASE.length())); 
         if (checkRepeatCharacter(getRandom, characterUsed, 
           characterUsed.size(), maxRepeatCharacter) == true) { 
          passwordGenerated.append(getRandom); 
          characterUsed.add(getRandom); 
          indexUsed.add(index); 
          lowerCaseLetterUsed++; 
          letterUsed++; 
          letterAndDigitUsed++; 
          passwordLength++; 
          if (letterUsed == minLetter) { 
           break; 
          } 
         } 
        } 
       } 
       if (letterAndDigitUsed == minLetterAndDigit) { 
        break; 
       } 
       upperCaseLetterUsed = 0; 
       for (int i = 0; upperCaseLetterUsed < minUpperCaseLetter; i++) { 
        int index = getRandomNumber(0, length); 
        if (checkUsedIndex(index, indexUsed) == true) { 
         getRandom = UPPERCASE.charAt(getRandomNumber(0, 
           UPPERCASE.length())); 
         if (checkRepeatCharacter(getRandom, characterUsed, 
           characterUsed.size(), maxRepeatCharacter) == true) { 
          passwordGenerated.append(getRandom); 
          characterUsed.add(getRandom); 
          indexUsed.add(index); 
          lowerCaseLetterUsed++; 
          letterUsed++; 
          letterAndDigitUsed++; 
          passwordLength++; 
          if (letterUsed == minLetter) { 
           break; 
          } 
         } 
        } 
       } 
       if (letterAndDigitUsed == minLetterAndDigit) { 
        break; 
       } 
      } 
      for (int i = 0; digitUsed < minDigit; i++) { 
       int index = getRandomNumber(0, length); 
       if (checkUsedIndex(index, indexUsed) == true) { 
        getRandom = DIGIT.charAt(getRandomNumber(0, 
          DIGIT.length())); 
        if (checkRepeatCharacter(getRandom, characterUsed, 
          characterUsed.size(), maxRepeatCharacter) == true) { 
         passwordGenerated.append(getRandom); 
         characterUsed.add(getRandom); 
         indexUsed.add(index); 
         digitUsed++; 
         letterAndDigitUsed++; 
         passwordLength++; 
        } 
       } 
      } 
     } 
     for (int i = 0; specialCharacterUsed < minSpecialCharacter; i++) { 
      if (checkUsedIndex(i, indexUsed) == true) { 
       getRandom = specialCharacter.charAt(getRandomNumber(0, 
         specialCharacter.length())); 
       if (checkRepeatCharacter(getRandom, characterUsed, 
         characterUsed.size(), maxRepeatCharacter) == true) { 
        passwordGenerated.append(getRandom); 
        characterUsed.add(getRandom); 
        indexUsed.add(i); 
        specialCharacterUsed++; 
        passwordLength++; 
       } 
      } 
     } 
     for (int i = 0; i < length; i++) { 
      if (checkUsedIndex(i, indexUsed) == true) { 
       getRandom = ALL.charAt(getRandomNumber(0, ALL.length())); 
       if (checkRepeatCharacter(getRandom, characterUsed, 
         characterUsed.size(), maxRepeatCharacter) == true) { 
        passwordGenerated.append(getRandom); 
        characterUsed.add(getRandom); 
        indexUsed.add(i); 
        passwordLength++; 
       } 
      } 
     } 
    } 
    return passwordGenerated.toString(); 
} 
2

Я хотел бы взглянуть на то, как VT-пароль:

https://code.google.com/p/vt-middleware/wiki/vtpassword

В дополнение к предоставлению гибких механизмов для работы с проверкой пароля на основе некоторых довольно стандартных требуемых характеристик , он обеспечивает поддержку для генерации паролей, которые соответствуют условиям, определенным списком «правил персонажа»:

https://code.google.com/p/vt-middleware/wiki/vtpassword#Generating_passwords

Стоит отметить, что проект окончил инкубацию и теперь известен как Passay - http://www.passay.org/.

Текущий password generator JavaDocs не отражает тот же набор правил символов, которые были доступны с помощью vt-password. Вы можете либо запустить с vt-паролем какое-то время, либо предоставить свои собственные версии CharacterRule для работы с генератором Passay (+ валидатор, если это необходимо).