web-dev-qa-db-ja.com

Javaパスワードジェネレーター

私はパスワードを作成するJavaプログラムを作成しようとしています。すべて小文字、小文字と大文字、小文字と大文字と数字、小文字と大文字と数字と句読点、そしてプログラムも作成する必要がありますユーザーが選択し、ユーザーが選択したものに応じてパスワードの長さを生成する必要があるパスワードの1つです。ユーザーが選択するためのパスワードオプションを既に生成し、1つを選択するように促しています。上記のパスワードタイプを作成するために、ある人がASCII値を使用してからテキストに変換することを提案しました。テキストに変換する方法は知っていますが、数字、文字が表示されます、そして句読点。ASCII小文字だけの値を生成できる方法はありますか?また、ユーザーが指定した長さに応じてパスワードを生成するにはどうすればよいですか?

15
word word

この不変クラスを使用します。
ビルダーパターンを使用します。
拡張機能はサポートしていません

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

これは使用例です。

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

org.Apache.commons.lang.RandomStringUtilsを使用して、ランダムなテキスト/パスワードを生成できます。たとえば、 this リンクを参照してください。

17
Dark Knight

念のためにそれは誰かのために役立ちます。 Java範囲に基づく標準ASCII 8クラスによる1行のランダムパスワードジェネレーター:

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

または

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

ここで、パスワードの長さは10です。もちろん、ある範囲でランダムに設定することもできます。また、文字はASCIIの範囲33〜122で、すべて特殊な記号、数字の大文字と小文字です。

小文字のみが必要な場合は、範囲を設定できます:97-122

5
engilyin

次の方法でできます:

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

...自分で記入しなければならない部分。)

ユーザーが選択したオプションから、対応する文字クラスを連結することにより、選択する文字列を作成します。

最後に、ループを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();
3
Ingo

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

見てください

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

2
Jukka Nikki

数字、文字、句読点をランダムに選択でき、ディメンションがあります。 ANSI番号は30〜39、小文字は61-7A、ANSなどです。 ascii tables を使用します

1
Andrew Evt
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();

    }

}
1
F_SO_K

Java Unix "pwgen"の実装を試すことができます。 https://github.com/antiso/pwgen-gae BitbucketのCLIを使用したjpwgenライブラリ実装へのリンクと、GAEデプロイ済みサンプルへのリンクが含まれています。

0
Vladimir Sosnin

それが私だったら、文字の配列(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メソッドに渡す方法になります。

そのための1つの方法は、許可するルールに一致する正規表現ルールのリストを設定し、ルールを介してすべての文字を送信することです。..ルールに一致する場合は追加します。

次のような関数を考えます。

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("[a-z]", Character.MAX_VALUE);

または、すべての「Word」文字のリスト:

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

次に、要件に一致する正規表現を選択し、毎回再利用される有効な文字の配列を「保存」する場合になります。 (パスワードを生成するたびに文字を生成しないでください。..)

0
rolfl

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

お役に立てれば! :)

0
Pastasaurus Rex