我正在使用此函数生成长度为11的随机密码,如this帖子所示:
import java.util.Random;
public class RandomPassword {
public static void main(String[] args){
RandomPassword r = new RandomPassword(11);
System.out.print(r.nextString());
}
private static final char[] symbols;
static {
StringBuilder tmp = new StringBuilder();
for (char ch = '0'; ch <= '9'; ++ch)
tmp.append(ch);
for (char ch = 'a'; ch <= 'z'; ++ch)
tmp.append(ch);
for (char ch = 'A'; ch <= 'Z'; ++ch)
tmp.append(ch);
symbols = tmp.toString().toCharArray();
}
private final Random random = new Random();
private final char[] buf;
public RandomPassword(int length) {
if (length < 1)
throw new IllegalArgumentException("length < 1: " + length);
buf = new char[length];
}
public String nextString() {
for (int idx = 0; idx < buf.length; ++idx)
buf[idx] = symbols[random.nextInt(symbols.length)];
return new String(buf);
}
}
但是我需要修改它,这样我才能保证至少有一个大写字母,一个数字和一个小写字母。现在,密码可能包含所有大写/小写/数字,我们至少需要AD中的一个接受。感谢任何帮助。谢谢。
***我被告知最好像这样在nextString()
中循环:
public String nextString() {
for (int idx = 0; idx < buf.length; ++idx)
if(buf[buf.length%3].equals(num/lower/cap)){
buf[idx] = symbols[random.nextInt(symbols.length)];
}
.
.
.
return new String(buf);
}
您怎么看?
答案 0 :(得分:3)
这可以防止循环,并且还具有真正随机的好处。
或者,如果你可以丢失一些熵,你可以:
答案 1 :(得分:1)
遍历数组中的字符以确保每个字符类都包含在其中。然后,如果失败,只需生成一个新的随机字符串。这样可以确保所有内容都包含在内,并且不会经常验证。
答案 2 :(得分:1)
我建议常规表达式搜索一组预先设定的字符/数字大写/小写和错误信息
public String getPassword(){
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG", "SUN");
byte[] salt = new byte[16];
sr.nextBytes(salt);
return wellformedPassword(salt.toString()) ? salt.toString() : secured(salt.toString());
}
public String secured(String pass){
return string1.replaceFirst(Pattern.quote("[a-z]", "Z");
}
public boolean wellformedPassword(String pass){
return checkRegExp(pass, "\\d")
&& checkRegExp(pass, "[A-Z]")
&& checkRegExp(pass, "[a-z]");
}
public boolean checkRegExp(String str, String pattern){
Pattern p = Pattern.compile(pattern);
Matcher n = p.matcher(str);
return n.find();
}
SHA确保你小写字母和数字,然后你只需要转一个(在我的情况下)或更多到上面。
这是一种可以改进的虚拟方法。分享您的代码,以便我以后无法为其他任何人编辑我的答案。
你可以得到那个字符并把它变成上面而不是Z,但我想你可以开始使用它。
答案 3 :(得分:0)
这个“作弊”(比它可能弱),但它符合通常的要求(或者可以修改以满足它们):
import java.util.Random;
public class Password {
private static final String UPPER = "ABCDEFGHIJKLMNPQRSTUVWXYZ";
private static final String LOWER = "abcdefghijklmnpqrstuvwxyz";
private static final String NUMBER = "123456789";
private static final String SPECIAL = "!@#$%&*+?";
private Random randGen = new Random();
public static void main(String[] argv) {
Password me = new Password();
for (int i = 0; i <= 10; i++) {
me.printPassword();
}
}
private void printPassword() {
StringBuffer buf = new StringBuffer();
buf.append(LOWER.charAt(Math.abs(randGen.nextInt()) % LOWER.length()));
buf.append(LOWER.charAt(Math.abs(randGen.nextInt()) % LOWER.length()));
buf.append(NUMBER.charAt(Math.abs(randGen.nextInt()) % NUMBER.length()));
for (int i = 0; i <= 4; i++) {
buf.append(LOWER.charAt(Math.abs(randGen.nextInt()) % LOWER.length()));
}
buf.append(UPPER.charAt(Math.abs(randGen.nextInt()) % UPPER.length()));
buf.append(LOWER.charAt(Math.abs(randGen.nextInt()) % LOWER.length()));
System.out.println(buf.toString());
}
}
我有另一种算法更好,但丢失了。
(我喜欢打印多个“建议”,然后选择一个最容易记住的建议。)
答案 4 :(得分:0)
我真的不知道它有多可靠但只是一次尝试
List<Character> listOfUpperCaseLetter = new ArrayList<Character>();
for(int i = 65;i<91;i++){
char ch = (char)i;
listOfUpperCaseLetter.add(ch);
}
List<Character> listOfLowerCaseLetter = new ArrayList<Character>();
for(int i = 97;i<123;i++){
char ch = (char)i;
listOfLowerCaseLetter.add(ch);
}
List<Integer> listOfInt = new ArrayList<Integer>();
for(int i =0;i<10;i++){
listOfInt.add(i);
}
StringBuilder br = new StringBuilder();
Collections.shuffle(listOfLowerCaseLetter);
Collections.shuffle(listOfUpperCaseLetter);
Collections.shuffle(listOfInt);
br.append(listOfUpperCaseLetter.get(0));
br.append(listOfLowerCaseLetter.get(1));
br.append(listOfLowerCaseLetter.get(3));
br.append(listOfInt.get(1));
br.append(listOfInt.get(0));
br.append(listOfLowerCaseLetter.get(2));
br.append(listOfUpperCaseLetter.get(1));
br.append(listOfLowerCaseLetter.get(0));
br.append(listOfUpperCaseLetter.get(2));
br.append(listOfInt.get(2));
System.out.println(br.toString());
答案 5 :(得分:0)
我只是添加了if/else
语句,说要添加symbols
数组的某些成员(0-10,11-35,36-61)。这保证了所需要的。有时最简单的答案是最好的答案。谢谢你的想法。
if (idx == 0){
buf[idx] = symbols[random.nextInt(10)];
}else if (idx == 1){
buf[idx] = symbols[10 + random.nextInt(35-10+1)];
}else if(idx == 2){
buf[idx] = symbols[36 + random.nextInt(61-36+1)];
}else{
buf[idx] = symbols[random.nextInt(symbols.length)];
}