Java密码生成器

我正在尝试创建一个创建密码的java程序,可以是全部小写,小写和大写,小写和大写以及数字,小写和大写以及数字和标点符号,程序还必须创建用户选择的密码之一并且必须根据用户选择的内容生成密码长度。 我已经为用户选择了密码选项,并提示他选择一个。 我现在仍然坚持如何创建上面提到的密码类型。 一个人建议我使用ASCII值,然后将它们转换为文本。 我知道如何将它们转换为文本,但它会显示数字,字母和标点符号。 有什么办法可以只为小写字母生成ASCII值吗? 另外,我如何根据用户提供的密码生成密码?

我使用这个不可变类。
它使用构建器模式
它不支持扩展

public final class PasswordGenerator { private static final String LOWER = "abcdefghijklmnopqrstuvwxyz"; private static final String UPPER = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; private static final String DIGITS = "0123456789"; private static final String PUNCTUATION = "!@#$%&*()_+-=[]|,./?><"; private boolean useLower; private boolean useUpper; private boolean useDigits; private boolean usePunctuation; private PasswordGenerator() { throw new UnsupportedOperationException("Empty constructor is not supported."); } private PasswordGenerator(PasswordGeneratorBuilder builder) { this.useLower = builder.useLower; this.useUpper = builder.useUpper; this.useDigits = builder.useDigits; this.usePunctuation = builder.usePunctuation; } public static class PasswordGeneratorBuilder { private boolean useLower; private boolean useUpper; private boolean useDigits; private boolean usePunctuation; public PasswordGeneratorBuilder() { this.useLower = false; this.useUpper = false; this.useDigits = false; this.usePunctuation = false; } /** * Set true in case you would like to include lower characters * (abc...xyz). Default false. * * @param useLower true in case you would like to include lower * characters (abc...xyz). Default false. * @return the builder for chaining. */ public PasswordGeneratorBuilder useLower(boolean useLower) { this.useLower = useLower; return this; } /** * Set true in case you would like to include upper characters * (ABC...XYZ). Default false. * * @param useUpper true in case you would like to include upper * characters (ABC...XYZ). Default false. * @return the builder for chaining. */ public PasswordGeneratorBuilder useUpper(boolean useUpper) { this.useUpper = useUpper; return this; } /** * Set true in case you would like to include digit characters (123..). * Default false. * * @param useDigits true in case you would like to include digit * characters (123..). Default false. * @return the builder for chaining. */ public PasswordGeneratorBuilder useDigits(boolean useDigits) { this.useDigits = useDigits; return this; } /** * Set true in case you would like to include punctuation characters * (!@#..). Default false. * * @param usePunctuation true in case you would like to include * punctuation characters (!@#..). Default false. * @return the builder for chaining. */ public PasswordGeneratorBuilder usePunctuation(boolean usePunctuation) { this.usePunctuation = usePunctuation; return this; } /** * Get an object to use. * * @return the {@link gr.idrymavmela.business.lib.PasswordGenerator} * object. */ public PasswordGenerator build() { return new PasswordGenerator(this); } } /** * This method will generate a password depending the use* properties you * define. It will use the categories with a probability. It is not sure * that all of the defined categories will be used. * * @param length the length of the password you would like to generate. * @return a password that uses the categories you define when constructing * the object with a probability. */ public String generate(int length) { // Argument Validation. if (length <= 0) { return ""; } // Variables. StringBuilder password = new StringBuilder(length); Random random = new Random(System.nanoTime()); // Collect the categories to use. List charCategories = new ArrayList<>(4); if (useLower) { charCategories.add(LOWER); } if (useUpper) { charCategories.add(UPPER); } if (useDigits) { charCategories.add(DIGITS); } if (usePunctuation) { charCategories.add(PUNCTUATION); } // Build the password. for (int i = 0; i < length; i++) { String charCategory = charCategories.get(random.nextInt(charCategories.size())); int position = random.nextInt(charCategory.length()); password.append(charCategory.charAt(position)); } return new String(password); } } 

这是一个用法示例,

 PasswordGenerator passwordGenerator = new PasswordGenerator.PasswordGeneratorBuilder() .useDigits(true) .useLower(true) .useUpper(true) .build(); String password = passwordGenerator.generate(8); // output ex.: lrU12fmM 75iwI90o 

您可以使用org.apache.commons.lang.RandomStringUtils生成随机文本/密码。 例如,请参阅此链接。

你可以这样做:

 String lower = "abc...xyz"; String digits = "0123456789"; String punct = "!#$&..."; String ... // further characer classes 

(注意...你必须自己填写的部分。)

从用户选择的选项中,您可以通过连接相应的字符类来创建可供选择的字符串。

最后你运行一个循环n次,其中n是想要的字符数。 在每一轮中,您从您创建的String中选择一个随机字符并将其添加到结果中:

 StringBuilder sb = new StringBuilder(); int n = ....; // how many characters in password String set = ....; // characters to choose from for (i= 0; i < n; i++) { int k = ....; // random number between 0 and set.length()-1 inklusive sb.append(set.charAt(k)); } String result = sb.toString(); 

Apache commons text对随机字符串生成有很好的选择。 Builder用于构建生成器,此生成器易于用于生成所需的密码。

  // Generates a 20 code point string, using only the letters az RandomStringGenerator generator = new RandomStringGenerator.Builder() .withinRange('a', 'z').build(); String randomLetters = generator.generate(20); 

请参见

https://commons.apache.org/proper/commons-text/javadocs/api-release/org/apache/commons/text/RandomStringGenerator.html

您可以随机选择具有维度的数字,字母和标点符号。 Ansii数字从30到39,小写字母从61-7A,ans等等。 使用ansii表

如果是我,我将构建字符数组( char[] ... ),表示您将允许的各种字符集,然后在您的生成器方法中选择适当的字符数组,并从中生成密码。 复杂的部分然后变得创建字符数组……

 public String generate(char[] validchars, int len) { char[] password = new char[len]; Random rand = new Random(System.nanoTime()); for (int i = 0; i < len; i++) { password[i] = validchars[rand.nextInt(validchars.length)]; } return new String(password); } 

然后你的问题只是生成char []数组,代表你拥有的各种规则,以及如何将该集合传递给generate方法。

一种方法是设置一个与你允许的规则匹配的正则表达式规则列表,然后通过规则发送每个字符....如果它们符合规则,那么添加它们.....

考虑一个看起来像这样的函数:

 public static final char[] getValid(final String regex, final int lastchar) { char[] potential = new char[lastchar]; // 32768 is not huge.... int size = 0; final Pattern pattern = Pattern.compile(regex); for (int c = 0; c <= lastchar; c++) { if (pattern.matcher(String.valueOf((char)c)).matches()) { potential[size++] = (char)c; } } return Arrays.copyOf(potential, size); } 

然后,您可以获得一个无字符字符数组(仅限小写):

 getValid("[az]", Character.MAX_VALUE); 

或者,所有“单词”字符的列表:

 getValid("\\w", Character.MAX_VALUE); 

然后,选择正则表达式以满足您的要求,并“存储”每次要重用的有效字符数组。 (每次生成密码时都不要生成字符....)

我创建了一个简单的程序,用ASCII编号填充ArrayList ,然后使用SecureRandom数字生成器在for循环中从它们中随机化,您可以在其中设置所需的字符数。

 import java.security.SecureRandom; import java.util.ArrayList; import java.util.List; public class PassGen { private String str; private int randInt; private StringBuilder sb; private List l; public PassGen() { this.l = new ArrayList<>(); this.sb = new StringBuilder(); buildPassword(); } private void buildPassword() { //Add ASCII numbers of characters commonly acceptable in passwords for (int i = 33; i < 127; i++) { l.add(i); } //Remove characters /, \, and " as they're not commonly accepted l.remove(new Integer(34)); l.remove(new Integer(47)); l.remove(new Integer(92)); /*Randomise over the ASCII numbers and append respective character values into a StringBuilder*/ for (int i = 0; i < 10; i++) { randInt = l.get(new SecureRandom().nextInt(91)); sb.append((char) randInt); } str = sb.toString(); } public String generatePassword() { return str; } } 

希望这可以帮助! 🙂