当前位置: 首页 > 知识库问答 >
问题:

在java中生成具有大量限制的随机密码

何玺
2023-03-14

我想创建一个密码生成器,根据用户设置的限制创建密码。限制是:

  1. 最小密码长度
  2. 最大密码长度
  3. 最小字母和数字
  4. 最小字母
  5. 最小大写字母
  6. 最小小写字母
  7. 最小数字
  8. 最大重复字符数

我通过谷歌观察,大多数示例代码不符合我需要的要求。所以我即兴创作了这样的代码:

private char[] GeneratePassword(int minLength, int maxLength,
        int maxRepeatCharacter, int minLetterAndDigit, int minLetter,
        int minLowerCaseLetter, int minUpperCaseLetter, int minDigit) {

    final String LETTER = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
    final String UPPERCASE = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    final String LOWERCASE = "abcdefghijklmnopqrstuvwxyz";
    final String DIGIT = "0123456789";
    final String[] randomSelector = {LETTER,UPPERCASE,LOWERCASE,DIGIT};

    int len = getRandomNumber(minLength, maxLength);
    char[] passwordGenerated = new char[len];
    char[] characterUsed = new char[len];
    int selection;
    int letterAndDigitUsed = 0;
    int letterUsed = 0;
    int lowerCaseLetterUsed = 0;
    int upperCaseLetterUsed = 0;
    int digitUsed = 0;
    int index = 0;

    if (minLength > maxLength) {
      // throw new IllegalArgumentException("Min.Length > Max.Length!");
    }

    if (minLetter + minDigit > minLetterAndDigit) {
      // throw new IllegalArgumentException("Error!");
    }

    while (index != len) {
        selection = getRandomNumber(0, randomSelector.length);
        if (selection == 0) {
            passwordGenerated[index] = LETTER.charAt(RandomUtils.nextInt(0,
                    LETTER.length()));
            if (checkRepeatCharacter(passwordGenerated[index],
                    characterUsed, index, maxRepeatCharacter) == false) {
                characterUsed[index] = passwordGenerated[index];
                index++;
                letterUsed++;
                letterAndDigitUsed++;
                break;
            }
        } else if (selection == 1) {
            passwordGenerated[index] = UPPERCASE.charAt(RandomUtils
                    .nextInt(0, UPPERCASE.length()));
            if (checkRepeatCharacter(passwordGenerated[index],
                    characterUsed, index, maxRepeatCharacter) == false) {
                characterUsed[index] = passwordGenerated[index];
                index++;
                upperCaseLetterUsed++;
                letterAndDigitUsed++;
                break;
            }
        } else if (selection == 2) {
            passwordGenerated[index] = LOWERCASE.charAt(RandomUtils
                    .nextInt(0, LOWERCASE.length()));
            if (checkRepeatCharacter(passwordGenerated[index],
                    characterUsed, index, maxRepeatCharacter) == false) {
                characterUsed[index] = passwordGenerated[index];
                index++;
                lowerCaseLetterUsed++;
                letterAndDigitUsed++;
                break;
            }
        } else if (selection == 3) {
            passwordGenerated[index] = DIGIT.charAt(RandomUtils.nextInt(0,
                    DIGIT.length()));
            if (checkRepeatCharacter(passwordGenerated[index],
                    characterUsed, index, maxRepeatCharacter) == false) {
                characterUsed[index] = passwordGenerated[index];
                index++;
                digitUsed++;
                letterAndDigitUsed++;
                break;
            }
        }
    }

    return passwordGenerated;
}

private boolean checkRepeatCharacter(char passwordGenerated,
        char[] passwordUsed, int index, int maxRepeatCharacter) {
    int characterRepeated = 0;
    for (int i = 0; i < index; i++) {
        if (String.valueOf(passwordUsed[i]).equals(
                String.valueOf(passwordGenerated))) {
            characterRepeated++;
            if (characterRepeated == maxRepeatCharacter) {
                return true;
            }
        }
    }
    return false;
}

private int getRandomNumber(int minLength, int maxLength) {
    Random r = new Random();
    return r.nextInt(maxLength - minLength) + minLength;
}

我遇到的问题是如何确保满足最低条件。同时,我不希望我的密码通过重复相同类型的字符来生成。

>

  • 示例:如果我将最大密码长度设置为 10,并且我想要的最小数字为 5。我更喜欢1jP2k3o4m9而不是57812aJ9tP

    第二个例子:如果我把我的最大密码长度设置为5,并且我想要一个最小小写字母3。我更喜欢Pj9mn而不是jkl5V

    如您所见,第二个生成的密码首先试图满足最低要求,然后只对其他字符类型进行随机选择。这将使密码更易受攻击。有没有办法做到这一点。

    参考:在Java中生成具有限制的随机密码

  • 共有2个答案

    谭伟
    2023-03-14

    我已经修复了我的代码。到目前为止,我已经测试过了,我按照要求完美地工作。我保留此代码,以防将来其他人需要它。

    private boolean checkRepeatCharacter(char randomCharacter,
            ArrayList<Character> passwordUsed, int usedLength,
            int maxRepeatCharacter) {
        int characterRepeated = 0;
        for (int i = 0; i < usedLength; i++) {
            if (String.valueOf(passwordUsed.get(i)).equals(
                    String.valueOf(randomCharacter))) {
                characterRepeated++;
                if (characterRepeated == maxRepeatCharacter) {
                    return false;
                }
            }
        }
        return true;
    }
    
    private boolean checkUsedIndex(int index, ArrayList<Integer> usedIndex) {
        for (int i = 0; i < usedIndex.size(); i++) {
            if (usedIndex.contains(index)) {
                return false;
            }
        }
        return true;
    }
    
    private int getRandomNumber(int minLength, int maxLength) {
        Random r = new Random();
        return r.nextInt(maxLength - minLength) + minLength;
    }
    
    public String generatePassword(int minLength, int maxLength,
            int maxRepeatCharacter, int minLetterAndDigit, int minLetter,
            int minLowerCaseLetter, int minUpperCaseLetter, int minDigit,
            int minSpecialCharacter, String specialCharacter) {
    
        final String LOWERCASE = "abcdefghijklmnopqrstuvwxyz";
        final String UPPERCASE = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        final String DIGIT = "0123456789";
        StringBuilder ALL = new StringBuilder();
        ALL.append(LOWERCASE);
        ALL.append(UPPERCASE);
        ALL.append(DIGIT);
        ALL.append(specialCharacter);
        ALL.toString();
    
        char getRandom;
        int length = 0;
        StringBuilder passwordGenerated = new StringBuilder();
        ArrayList<Character> characterUsed = new ArrayList<Character>();
        ArrayList<Integer> indexUsed = new ArrayList<Integer>();
    
        int passwordLength = 0;
        int lowerCaseLetterUsed = 0;
        int upperCaseLetterUsed = 0;
        int letterUsed = 0;
        int digitUsed = 0;
        int letterAndDigitUsed = 0;
        int specialCharacterUsed = 0;
    
        if (minLength > maxLength) {
            throw new IllegalArgumentException("Min. Length > Max. Length!");
        }
    
        if (minUpperCaseLetter + minLowerCaseLetter > minLetter) {
            throw new RuntimeException(
                    "mininimum Lower Case + Minimum Uppercase cannot exceed minLetter");
        }
        if (minLetter + minDigit > minLetterAndDigit) {
            throw new RuntimeException(
                    "mininimum Letter + Minimum Digit cannot exceed minimum Letter And Digit");
        }
        if (minLetter + minDigit + minSpecialCharacter > maxLength) {
            throw new RuntimeException(
                    "minimum Digit + minimum Letter + Minimum Special Character cannot excced maximum Length");
        }
    
        while ((length < minLetter) && (length < minLetterAndDigit)) {
            length = getRandomNumber(minLength, maxLength);
        }
    
        while (passwordLength != length) {
            while (letterAndDigitUsed < minLetterAndDigit) {
                while (letterUsed < minLetter) {
                    lowerCaseLetterUsed = 0;
                    for (int i = 0; lowerCaseLetterUsed < minLowerCaseLetter; i++) {
                        int index = getRandomNumber(0, length);
                        if (checkUsedIndex(index, indexUsed) == true) {
                            getRandom = LOWERCASE.charAt(getRandomNumber(0,
                                    LOWERCASE.length()));
                            if (checkRepeatCharacter(getRandom, characterUsed,
                                    characterUsed.size(), maxRepeatCharacter) == true) {
                                passwordGenerated.append(getRandom);
                                characterUsed.add(getRandom);
                                indexUsed.add(index);
                                lowerCaseLetterUsed++;
                                letterUsed++;
                                letterAndDigitUsed++;
                                passwordLength++;
                                if (letterUsed == minLetter) {
                                    break;
                                }
                            }
                        }
                    }
                    if (letterAndDigitUsed == minLetterAndDigit) {
                        break;
                    }
                    upperCaseLetterUsed = 0;
                    for (int i = 0; upperCaseLetterUsed < minUpperCaseLetter; i++) {
                        int index = getRandomNumber(0, length);
                        if (checkUsedIndex(index, indexUsed) == true) {
                            getRandom = UPPERCASE.charAt(getRandomNumber(0,
                                    UPPERCASE.length()));
                            if (checkRepeatCharacter(getRandom, characterUsed,
                                    characterUsed.size(), maxRepeatCharacter) == true) {
                                passwordGenerated.append(getRandom);
                                characterUsed.add(getRandom);
                                indexUsed.add(index);
                                lowerCaseLetterUsed++;
                                letterUsed++;
                                letterAndDigitUsed++;
                                passwordLength++;
                                if (letterUsed == minLetter) {
                                    break;
                                }
                            }
                        }
                    }
                    if (letterAndDigitUsed == minLetterAndDigit) {
                        break;
                    }
                }
                for (int i = 0; digitUsed < minDigit; i++) {
                    int index = getRandomNumber(0, length);
                    if (checkUsedIndex(index, indexUsed) == true) {
                        getRandom = DIGIT.charAt(getRandomNumber(0,
                                DIGIT.length()));
                        if (checkRepeatCharacter(getRandom, characterUsed,
                                characterUsed.size(), maxRepeatCharacter) == true) {
                            passwordGenerated.append(getRandom);
                            characterUsed.add(getRandom);
                            indexUsed.add(index);
                            digitUsed++;
                            letterAndDigitUsed++;
                            passwordLength++;
                        }
                    }
                }
            }
            for (int i = 0; specialCharacterUsed < minSpecialCharacter; i++) {
                if (checkUsedIndex(i, indexUsed) == true) {
                    getRandom = specialCharacter.charAt(getRandomNumber(0,
                            specialCharacter.length()));
                    if (checkRepeatCharacter(getRandom, characterUsed,
                            characterUsed.size(), maxRepeatCharacter) == true) {
                        passwordGenerated.append(getRandom);
                        characterUsed.add(getRandom);
                        indexUsed.add(i);
                        specialCharacterUsed++;
                        passwordLength++;
                    }
                }
            }
            for (int i = 0; i < length; i++) {
                if (checkUsedIndex(i, indexUsed) == true) {
                    getRandom = ALL.charAt(getRandomNumber(0, ALL.length()));
                    if (checkRepeatCharacter(getRandom, characterUsed,
                            characterUsed.size(), maxRepeatCharacter) == true) {
                        passwordGenerated.append(getRandom);
                        characterUsed.add(getRandom);
                        indexUsed.add(i);
                        passwordLength++;
                    }
                }
            }
        }
        return passwordGenerated.toString();
    }
    
    墨宜人
    2023-03-14

    我会看看像vt-password这样的东西:

    https://code.google.com/p/vt-middleware/wiki/vtpassword

    除了基于一些相当标准的必需特征提供灵活的密码验证机制外,它还支持生成满足“字符规则”列表定义的条件的密码:

    https://code . Google . com/p/vt-middleware/wiki/vt password # Generating _ passwords

    值得注意的是,该项目已经从孵化阶段毕业,现在被称为帕塞-http://www.passay.org/.

    当前的密码生成器 JavaDocs 不反映 vt 密码中可用的同一组字符规则。您可以使用 vt 密码运行一段时间,也可以提供自己的 CharacterRule 实现以与 Passay 生成器(验证器,如果需要)配合使用。

     类似资料:
    • 问题内容: 我正在尝试在php中生成一个随机密码。 但是我得到所有的’a’s,返回类型是数组类型,我希望它是一个字符串。有关如何更正代码的任何想法? 谢谢。 问题答案: 安全警告 :不是加密安全的伪随机数生成器。寻找其他地方以在PHP中生成加密安全的伪随机字符串。 试试这个(使用代替,因为在字符串上总是):

    • 这是我的代码: null null 因此,一般来说,我想生成一个随机数量的divs和随机的位置。 不幸的是,这篇或这篇文章对我没有帮助。太具体了。 我会非常感谢你的帮助!

    • 本文向大家介绍Python生成随机密码,包括了Python生成随机密码的使用技巧和注意事项,需要的朋友参考一下 本人  python新手,使用的环境是python2.7,勿喷 以上就是本文的全部内容了,希望对大家学习python能够有所帮助。

    • 问题内容: 我们如何在Java中生成非常大的随机数?我说的是10000位数吗?我知道我们必须使用BigInteger,但是我们该怎么做呢?做这样的事情最有效的方法是什么?请提供一个小例子。谢谢。 问题答案: 嗯,一种方法是转到Random.org并下载二进制随机文件之一。这些文件是由大气噪声生成的,因此非常随机。我在国际象棋引擎中将其用于Zobrist键。 或者你可以去 这会给你你想要的。在此示例

    • 我正在做一个粒子在晶格中运动的随机行走模拟。因此,我必须创建大量的随机数,大约10^12及以上。目前,我正在使用C 11提供的可能性 问题是:我能做些什么来减少生成这些数字所需的CPU时间,以及对它们的质量有什么影响? 如您所见,我尝试了不同的引擎,但这对CPU时间没有太大影响。此外,我的uniform01(gen)和generate\u canonical之间有什么区别 编辑:通过阅读答案,我得

    • 问题内容: 如何使用Java创建符合系统长度和字符集要求的随机密码? 我必须创建一个随机密码,密码长度为10-14个字符,并且至少具有一个大写字母,一个小写字母和一个特殊字符。不幸的是,某些特殊字符 太 特殊而无法使用,因此我不能仅使用打印的ASCII。 该站点上的许多示例都会生成一个随机的密码或会话密钥,而在字符中没有足够的熵,或者在像上面给出的那样的商业环境中没有现实的要求,因此,我想提出更明