我想创建一个密码生成器,根据用户设置的限制创建密码。限制是:
- 最小密码长度
- 最大密码长度
- 最少的字母和数字
- 最少字母
- 最小大写字母
- 最小小写字母
- 最小数字
- 最大重复字符数
我通过谷歌查找,大部分示例代码不符合我需要的要求。所以我即兴创作了这样的代码:
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 = "0123456789";
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;
}
我遇到的问题是如何确保满足最低条件。同时,我不希望通过重复相同类型的字符来生成我的密码。
示例:如果我将最大密码长度设置为 10,而我希望最小数字为 5。我更喜欢使用
1jP2k3o4m9
而不是57812aJ9tP
。第二个示例:如果我将最大密码长度设置为 5,并且我希望最小小写字母为 3。我更喜欢使用
Pj9mn
而不是jkl5V
.
如您所见,第二次生成的密码试图先满足最低要求,然后才对其他字符类型进行随机选择。这将使密码更容易受到攻击。有没有办法做这个算法。
最佳答案
我会看一下类似 vt-password 的东西:
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不反射(reflect) vt-password 可用的同一组字符规则。您可以使用 vt-password 运行一段时间,或者提供您自己的 CharacterRule
实现以与 Passay 生成器(+ validator ,如果还需要)一起工作。
关于java - 在java中生成有很多限制的随 secret 码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33512547/