我有兴趣使用以下属性生成(安全)随机字符串:
字符串的长度应为12-13位/字符长。
我知道Apache公共中有一个类可以帮助生成随机字符串,但是没有选项可以包含特殊字符。
我也知道其他一些类似的问题,但是没有一个能完全满足这些要求。
到目前为止,我已尝试过以下内容:
import java.security.SecureRandom;
public final class SessionIdentifierGenerator {
private SecureRandom random = new SecureRandom();
public String nextSessionId() {
return
new BigInteger(130, random).toString(32);
}
}
但它不包含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();
}
我知道我可以修改String AB以包含特殊字符但是保证字符串无法包含Atleast 1 upper,1 lower,1 digit和1个特殊字符。
我正在使用Java。
答案 0 :(得分:4)
您的最简单方法是生成包含任何允许符号的随机密码,然后测试是否符合条件:
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);
}
}
}
根据我的测试,所需迭代次数很少超过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
答案 1 :(得分:0)
设置数组/列表/任何字符。选择一个随机的小写字母并将其放入您的数组中。选择一个随机的大写字母并将其放入您的数组中。选择一个随机数字并将其放入数组中。选择一个随机的特殊字符并将其放入数组中。您的阵列中有四个字符,部分符合您的要求。
现在从字符串中随机选择多个字符:&#34; A-Za-z0-9 $&amp; @?&lt;&gt;〜!%#&#34;将每个选定的字符添加到字符数组中。
现在随机播放你的角色数组以搞乱前四个字符的顺序。
将混洗数组转换为字符串。
答案 2 :(得分:0)
以下内容适合我。请注意,如果您不想使用Random
,则可以传入特定的RandomUtils
实现。
public class RandomUtil {
public static final String ALPHABETIC_UPPERCASE_SYMBOLS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
public static final String ALPHABETIC_LOWERCASE_SYMBOLS = "abcdefghijklmnopqrstuvwxyz";
public static final String NUMERIC_SYMBOLS = "0123456789";
public static final String SPECIAL_SYMBOLS = "$&@?<>~!%#";
public static final String ALPHANUMERIC_AND_SPECIAL_SYMBOLS =
ALPHABETIC_UPPERCASE_SYMBOLS +
ALPHABETIC_LOWERCASE_SYMBOLS +
NUMERIC_SYMBOLS +
SPECIAL_SYMBOLS;
public static String generateRandomAlphanumericAndSpecialCharactersKey(int length) {
List<Character> chars = new ArrayList<>(length);
boolean hasUpper = false;
boolean hasLower = false;
boolean hasNumber = false;
boolean hasSpecial = false;
for (int i = 0; i < length; i++) {
// Make sure we have at least one upper, lower, number and special character.
// Then, fill randomly from set containing all characters.
if (!hasUpper) {
chars.add(ALPHABETIC_UPPERCASE_SYMBOLS.charAt(RandomUtils.nextInt(0, ALPHABETIC_UPPERCASE_SYMBOLS.length())));
hasUpper = true;
} else if (!hasLower) {
chars.add(ALPHABETIC_LOWERCASE_SYMBOLS.charAt(RandomUtils.nextInt(0, ALPHABETIC_LOWERCASE_SYMBOLS.length())));
hasLower = true;
} else if (!hasNumber) {
chars.add(NUMERIC_SYMBOLS.charAt(RandomUtils.nextInt(0, NUMERIC_SYMBOLS.length())));
hasNumber = true;
} else if (!hasSpecial) {
chars.add(SPECIAL_SYMBOLS.charAt(RandomUtils.nextInt(0, SPECIAL_SYMBOLS.length())));
hasSpecial = true;
} else {
chars.add(ALPHANUMERIC_AND_SPECIAL_SYMBOLS.charAt(RandomUtils.nextInt(0, ALPHANUMERIC_AND_SPECIAL_SYMBOLS.length())));
}
}
// Shuffle characters to mix up the first 4 characters
Collections.shuffle(chars);
return StringUtils.join(chars, "");
}
}