Java密码生成器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19743124/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 19:52:01  来源:igfitidea点击:

Java password generator

javapasswordsgenerator

提问by word word

I am trying to create a java program that creates a password, either all lowercase, lowercase and uppercase, lowercase and uppercase and numbers, lowercase and uppercase and numbers and punctuation and the program also has to create one of those password that the user picks and and has to generate a password length according to what the user picks. I have already generated the password options for the user to pick from and have prompted him to pick one. I am now stuck on how to create the password types that were mentioned above. One person suggested me to use ASCII values and then converting them to text. I know how to convert them to text, but it will display number, letters, and punctuations. Is there any way that I can just generate ASCII values for just lowercase letters? Also how will I generate a password according to the user's length that they give?

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

回答by Andrew Evt

You can randomly choose numbers, letters and punctuations, having a dimension. Ansii numbers are from 30 to 39, lowercase letters from 61-7A, ans so on. Use ansii tables

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

回答by Dark Knight

You can make use of org.apache.commons.lang.RandomStringUtilsto generate random text/passwords. Please refer to thislink for example.

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

回答by Ingo

You can do it this way:

你可以这样做:

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

(Note the ...parts you must fill out yourself.)

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

From the options the user chooses, you create a string of characters to choose from by concatenating the corresponding character classes.

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

Finally you run a loop n times, where n is the number of characters wanted. In each round, you pick a random character from the String you created and add it to the result:

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

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();

回答by rolfl

If it were me I would build up arrays of characters ( char[] ...) that represent the various sets of characters that you will allow, and then in your generator method you choose the appropriate character array, and generate the password from that. The complicated part then becomes creating the character arrays...

如果是我,我会构建字符数组 ( 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);
}

Then your problem simply becomes generating char[] arrays that represent the various rules you have, and how to pass that set in to the generate method.

那么您的问题就变成了生成代表您拥有的各种规则的 char[] 数组,以及如何将其传递给 generate 方法。

one way to do that is to set up a list of regular expression rules that match the rules you allow, and then to send every character through the rules.... and if they match the rules then add them.....

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

Consider a function that looks like:

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

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);
}

Then, you can get an array of aphabetic characters (lowercase only) with:

然后,您可以使用以下命令获取一组不发音字符(仅限小写):

getValid("[a-z]", Character.MAX_VALUE);

Or, a list of all 'word' characters with:

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

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

Then it becomes a case of choosing the regular expression to match your requirements, and 'storing' the array of valid characters to be reused each time. (Don't generate the characters each time you generate a password....)

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

回答by Vladimir Sosnin

You can try Java implementation of a Unix "pwgen". https://github.com/antiso/pwgen-gaeIt contains the link to jpwgen library implementation with CLI at Bitbucket and the link to GAE deployed sample.

您可以尝试使用 Unix“pwgen”的 Java 实现。 https://github.com/antiso/pwgen-gae它包含在 Bitbucket 上使用 CLI 实现 jpwgen 库的链接以及指向 GAE 部署示例的链接。

回答by Pastasaurus Rex

I've made a simple program that populates an ArrayListwith ASCII numbers, and then uses a SecureRandomnumber generator to randomise from them in a forloop, in which you can set the number of characters you want.

我制作了一个简单的程序,ArrayList用 ASCII 数字填充,然后使用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<Integer> 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;
    }
}

Hope this helps! :)

希望这可以帮助!:)

回答by George Siggouroglou

I use this immutable class.
It uses the builder pattern.
It doesn't support extension.

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

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<String> 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);
    }
}

This is a usage example,

这是一个使用示例,

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

回答by Jukka Nikki

Apache commons text has pretty good alternative for random string generation. Builder is used to construct generator, after this generator is easy to use for generation of needed passwords.

Apache commons text 是随机字符串生成的不错选择。Builder 用于构造生成器,此生成器之后易于用于生成所需的密码。

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

Please see

请参见

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

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

回答by engilyin

Just in case it will be useful for somebody. The one line random password generator by standard Java 8 classes based on the ASCII range:

以防万一它对某人有用。基于 ASCII 范围的标准 Java 8 类的一行随机密码生成器:

String password = new Random().ints(10, 33, 122).collect(StringBuilder::new,
        StringBuilder::appendCodePoint, StringBuilder::append)
        .toString();

or

或者

String password = new Random().ints(10, 33, 122).mapToObj(i -> String.valueOf((char)i)).collect(Collectors.joining());

Here the length of password is 10. Of course you may set it randomly in some range as well. And the characters are from the ASCII range 33-122 which are all special symbols, digits upper and lower cases.

这里密码的长度是10。当然你也可以在某个范围内随意设置。并且字符来自ASCII范围33-122,它们都是特殊符号,数字大写和小写。

If you need lower case letters only you just can set the range: 97-122

如果你只需要小写字母,你可以设置范围:97-122

回答by F_SO_K

import java.security.SecureRandom;
import java.util.Random;

public class PasswordHelper {        

    public static String generatePassword (int length) {

    //minimum length of 6
    if (length < 4) {
        length = 6;
    }

    final char[] lowercase = "abcdefghijklmnopqrstuvwxyz".toCharArray();
    final char[] uppercase = "ABCDEFGJKLMNPRSTUVWXYZ".toCharArray();
    final char[] numbers = "0123456789".toCharArray();
    final char[] symbols = "^$?!@#%&".toCharArray();
    final char[] allAllowed = "abcdefghijklmnopqrstuvwxyzABCDEFGJKLMNPRSTUVWXYZ0123456789^$?!@#%&".toCharArray();

    //Use cryptographically secure random number generator
    Random random = new SecureRandom();

    StringBuilder password = new StringBuilder(); 

    for (int i = 0; i < length-4; i++) {
        password.append(allAllowed[random.nextInt(allAllowed.length)]);
    }

    //Ensure password policy is met by inserting required random chars in random positions
    password.insert(random.nextInt(password.length()), lowercase[random.nextInt(lowercase.length)]);
    password.insert(random.nextInt(password.length()), uppercase[random.nextInt(uppercase.length)]);
    password.insert(random.nextInt(password.length()), numbers[random.nextInt(numbers.length)]);
    password.insert(random.nextInt(password.length()), symbols[random.nextInt(symbols.length)]);
    }

    return password.toString();

    }

}