我一直在寻找一种简单的Java算法来生成伪随机字母数字字符串。在我的情况下,它将被用作唯一的会话/密钥标识符,“很可能”在超过50万代的时间内是唯一的(我的需求实际上不需要更复杂的东西)。
理想情况下,我可以根据我的独特性需求指定长度。例如,生成的长度为12的字符串可能看起来像“AEYGF7K0DM1X”。
我一直在寻找一种简单的Java算法来生成伪随机字母数字字符串。在我的情况下,它将被用作唯一的会话/密钥标识符,“很可能”在超过50万代的时间内是唯一的(我的需求实际上不需要更复杂的东西)。
理想情况下,我可以根据我的独特性需求指定长度。例如,生成的长度为12的字符串可能看起来像“AEYGF7K0DM1X”。
当前回答
如果密码必须包含数字和字母特殊字符,则可以使用以下代码:
private static final String NUMBERS = "0123456789";
private static final String UPPER_ALPHABETS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
private static final String LOWER_ALPHABETS = "abcdefghijklmnopqrstuvwxyz";
private static final String SPECIALCHARACTERS = "@#$%&*";
private static final int MINLENGTHOFPASSWORD = 8;
public static String getRandomPassword() {
StringBuilder password = new StringBuilder();
int j = 0;
for (int i = 0; i < MINLENGTHOFPASSWORD; i++) {
password.append(getRandomPasswordCharacters(j));
j++;
if (j == 3) {
j = 0;
}
}
return password.toString();
}
private static String getRandomPasswordCharacters(int pos) {
Random randomNum = new Random();
StringBuilder randomChar = new StringBuilder();
switch (pos) {
case 0:
randomChar.append(NUMBERS.charAt(randomNum.nextInt(NUMBERS.length() - 1)));
break;
case 1:
randomChar.append(UPPER_ALPHABETS.charAt(randomNum.nextInt(UPPER_ALPHABETS.length() - 1)));
break;
case 2:
randomChar.append(SPECIALCHARACTERS.charAt(randomNum.nextInt(SPECIALCHARACTERS.length() - 1)));
break;
case 3:
randomChar.append(LOWER_ALPHABETS.charAt(randomNum.nextInt(LOWER_ALPHABETS.length() - 1)));
break;
}
return randomChar.toString();
}
其他回答
public static String randomSeriesForThreeCharacter() {
Random r = new Random();
String value = "";
char random_Char ;
for(int i=0; i<10; i++)
{
random_Char = (char) (48 + r.nextInt(74));
value = value + random_char;
}
return value;
}
您提到“简单”,但如果其他人正在寻找符合更严格安全要求的产品,您可能需要看看jpwgen。jpwgen在Unix中以pwgen为模型,非常可配置。
我认为这是这里最小的解决方案,或者几乎是最小的方案之一:
public String generateRandomString(int length) {
String randomString = "";
final char[] chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567890".toCharArray();
final Random random = new Random();
for (int i = 0; i < length; i++) {
randomString = randomString + chars[random.nextInt(chars.length)];
}
return randomString;
}
代码工作正常。如果您正在使用此方法,我建议您使用超过10个字符。在5个字符/30362次迭代时发生冲突。这花了9秒。
static final String AB = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
static SecureRandom rnd = new SecureRandom();
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();
}
我使用的是一个非常简单的Java8解决方案。只需根据您的需求进行定制。
...
import java.security.SecureRandom;
...
//Generate a random String of length between 10 to 20.
//Length is also randomly generated here.
SecureRandom random = new SecureRandom();
String sampleSet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_";
int stringLength = random.ints(1, 10, 21).mapToObj(x -> x).reduce((a, b) -> a).get();
String randomString = random.ints(stringLength, 0, sampleSet.length() - 1)
.mapToObj(x -> sampleSet.charAt(x))
.collect(Collector
.of(StringBuilder::new, StringBuilder::append,
StringBuilder::append, StringBuilder::toString));
我们可以使用它生成如下的字母数字随机字符串(返回的字符串将强制包含一些非数字字符以及一些数字字符):
public String generateRandomString() {
String sampleSet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_";
String sampleSetNumeric = "0123456789";
String randomString = getRandomString(sampleSet, 10, 21);
String randomStringNumeric = getRandomString(sampleSetNumeric, 10, 21);
randomString = randomString + randomStringNumeric;
//Convert String to List<Character>
List<Character> list = randomString.chars()
.mapToObj(x -> (char)x)
.collect(Collectors.toList());
Collections.shuffle(list);
//This is needed to force a non-numeric character as the first String
//Skip this for() if you don't need this logic
for(;;) {
if(Character.isDigit(list.get(0))) Collections.shuffle(list);
else break;
}
//Convert List<Character> to String
randomString = list.stream()
.map(String::valueOf)
.collect(Collectors.joining());
return randomString;
}
//Generate a random number between the lower bound (inclusive) and upper bound (exclusive)
private int getRandomLength(int min, int max) {
SecureRandom random = new SecureRandom();
return random.ints(1, min, max).mapToObj(x -> x).reduce((a, b) -> a).get();
}
//Generate a random String from the given sample string, having a random length between the lower bound (inclusive) and upper bound (exclusive)
private String getRandomString(String sampleSet, int min, int max) {
SecureRandom random = new SecureRandom();
return random.ints(getRandomLength(min, max), 0, sampleSet.length() - 1)
.mapToObj(x -> sampleSet.charAt(x))
.collect(Collector
.of(StringBuilder::new, StringBuilder::append,
StringBuilder::append, StringBuilder::toString));
}