私はパスワードを作成するJavaプログラムを作成しようとしています。すべて小文字、小文字と大文字、小文字と大文字と数字、小文字と大文字と数字と句読点、そしてプログラムも作成する必要がありますユーザーが選択し、ユーザーが選択したものに応じてパスワードの長さを生成する必要があるパスワードの1つです。ユーザーが選択するためのパスワードオプションを既に生成し、1つを選択するように促しています。上記のパスワードタイプを作成するために、ある人が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<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
org.Apache.commons.lang.RandomStringUtils
を使用して、ランダムなテキスト/パスワードを生成できます。たとえば、 this リンクを参照してください。
念のためにそれは誰かのために役立ちます。 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
次の方法でできます:
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();
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);
見てください
数字、文字、句読点をランダムに選択でき、ディメンションがあります。 ANSI番号は30〜39、小文字は61-7A、ANSなどです。 ascii tables を使用します
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();
}
}
Java Unix "pwgen"の実装を試すことができます。 https://github.com/antiso/pwgen-gae BitbucketのCLIを使用したjpwgenライブラリ実装へのリンクと、GAEデプロイ済みサンプルへのリンクが含まれています。
それが私だったら、文字の配列(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);
次に、要件に一致する正規表現を選択し、毎回再利用される有効な文字の配列を「保存」する場合になります。 (パスワードを生成するたびに文字を生成しないでください。..)
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;
}
}
お役に立てれば! :)