生成包含字母数字和特殊字符的随机字符串?

And*_*lth 0 java string random passwords

我有兴趣生成具有以下属性的(安全)随机字符串:

  1. 至少 1 个大写字母
  2. 至少 1 个小写字母
  3. 0-9 至少 1 位数字
  4. 至少一个特殊字符来自字符 $&@?<>~!%#

字符串的长度应为 12-13 位/字符长。

我知道 Apache commons 中有一个类可以帮助生成随机字符串,但是没有包含特殊字符的选项。

我也知道关于 SO 的其他一些类似问题,但是它们都没有完全解决这些要求。

到目前为止,我已经尝试了以下方法:

import java.security.SecureRandom;

public final class SessionIdentifierGenerator {
  private SecureRandom random = new SecureRandom();

  public String nextSessionId() {
    return 

    new BigInteger(130, random).toString(32);
      }
    }
Run Code Online (Sandbox Code Playgroud)

但它不包含来自 4 个点中的每一个的字符集。

我也试过:

static final String AB = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
static Random rnd = new Random();

String randomString( int len ) 
{
   StringBuilder sb = new StringBuilder( len );
   for(int i = 0; i < len; i++) 
      sb.append(AB.charAt( rnd.nextInt(AB.length())));
   return sb.toString();
}
Run Code Online (Sandbox Code Playgroud)

我知道我可以修改字符串 AB 以包含特殊字符,但无法保证字符串将包含至少 1 个上位、1 个下位、1 个数字和 1 个特殊字符。

我正在使用 Java。

Tag*_*eev 5

在您的情况下,最简单的方法是生成包含任何允许符号的随机密码,然后测试是否满足条件:

private static final String symbols = 
     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789$&@?<>~!%#";

public static String genPassword(Random r) {
    while(true) {
        char[] password = new char[r.nextBoolean()?12:13];
        boolean hasUpper = false, hasLower = false, hasDigit = false, hasSpecial = false;
        for(int i=0; i<password.length; i++) {
            char ch = symbols.charAt(r.nextInt(symbols.length()));
            if(Character.isUpperCase(ch))
                hasUpper = true;
            else if(Character.isLowerCase(ch))
                hasLower = true;
            else if(Character.isDigit(ch))
                hasDigit = true;
            else
                hasSpecial = true;
            password[i] = ch;
        }
        if(hasUpper && hasLower && hasDigit && hasSpecial) {
            return new String(password);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

根据我的测试,所需的迭代次数很少超过 5,并且在超过一半的测试中,第一个生成的密码符合标准。虽然不要强迫你的用户记住这样的密码!以下是它们的外观:

c3h$oyuKcZZl
Si4e8F4sWjy#i
V$9WwW7zJ8ba
~9htwMwcFc!s
wBm94~AH%z%MU
p4TE36S&Y>J14
R9Bsqq@23eYk
PTfcvR5u?piZQ
CE8ot>a74PmZP
4zAco~P6Xuf3E
aiv?VDN4j9pE
Run Code Online (Sandbox Code Playgroud)