我一直在寻找一种简单的Java算法来生成伪随机字母数字字符串。在我的情况下,它将被用作唯一的会话/密钥标识符,“很可能”在超过50万代的时间内是唯一的(我的需求实际上不需要更复杂的东西)。
理想情况下,我可以根据我的独特性需求指定长度。例如,生成的长度为12的字符串可能看起来像“AEYGF7K0DM1X”。
我一直在寻找一种简单的Java算法来生成伪随机字母数字字符串。在我的情况下,它将被用作唯一的会话/密钥标识符,“很可能”在超过50万代的时间内是唯一的(我的需求实际上不需要更复杂的东西)。
理想情况下,我可以根据我的独特性需求指定长度。例如,生成的长度为12的字符串可能看起来像“AEYGF7K0DM1X”。
当前回答
另一个解决方案。。。
public static String generatePassword(int passwordLength) {
int asciiFirst = 33;
int asciiLast = 126;
Integer[] exceptions = { 34, 39, 96 };
List<Integer> exceptionsList = Arrays.asList(exceptions);
SecureRandom random = new SecureRandom();
StringBuilder builder = new StringBuilder();
for (int i=0; i<passwordLength; i++) {
int charIndex;
do {
charIndex = random.nextInt(asciiLast - asciiFirst + 1) + asciiFirst;
}
while (exceptionsList.contains(charIndex));
builder.append((char) charIndex);
}
return builder.toString();
}
其他回答
给定一些字符(AllCharacters),您可以随机选择字符串中的一个字符。然后使用for循环重复获取随机字符。
public class MyProgram {
static String getRandomString(int size) {
String AllCharacters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
StringBuilder sb = new StringBuilder(size);
int length = AllCharacters.length();
for (int i = 0; i < size; i++) {
sb.append(AllCharacters.charAt((int)(length * Math.random())));
}
return sb.toString();
}
public static void main(String[] args) {
System.out.println(MyProgram.getRandomString(30));
}
}
在沙盒上试试另请参阅其他语言实现随机字符串生成器
我不太喜欢这些关于“简单”解决方案的答案:S
我会选择简单的;),纯Java,一行(熵基于随机字符串长度和给定字符集):
public String randomString(int length, String characterSet) {
return IntStream.range(0, length).map(i -> new SecureRandom().nextInt(characterSet.length())).mapToObj(randomInt -> characterSet.substring(randomInt, randomInt + 1)).collect(Collectors.joining());
}
@Test
public void buildFiveRandomStrings() {
for (int q = 0; q < 5; q++) {
System.out.println(randomString(10, "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")); // The character set can basically be anything
}
}
或者(更易读的老方法)
public String randomString(int length, String characterSet) {
StringBuilder sb = new StringBuilder(); // Consider using StringBuffer if needed
for (int i = 0; i < length; i++) {
int randomInt = new SecureRandom().nextInt(characterSet.length());
sb.append(characterSet.substring(randomInt, randomInt + 1));
}
return sb.toString();
}
@Test
public void buildFiveRandomStrings() {
for (int q = 0; q < 5; q++) {
System.out.println(randomString(10, "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")); // The character set can basically be anything
}
}
但另一方面,你也可以使用UUID,它具有相当好的熵:
UUID.randomUUID().toString().replace("-", "")
您可以使用UUID类及其getLeastSignificantBits()消息来获取64位随机数据,然后将其转换为基数36的数字(即由0-9、a-Z组成的字符串):
Long.toString(Math.abs( UUID.randomUUID().getLeastSignificantBits(), 36));
这将产生一个长达13个字符的字符串。我们使用Math.abs()来确保没有负号潜入。
这里有一个简单的一行代码,使用UUID作为字符基础,可以指定(几乎)任何长度。(是的,我知道以前有人建议使用UUID。)
public static String randString(int length) {
return UUID.randomUUID().toString().replace("-", "").substring(0, Math.min(length, 32)) + (length > 32 ? randString(length - 32) : "");
}
如果您愿意使用Apache类,可以使用org.Apache.mons.text.RandomStringGenerator(Apache commons文本)。
例子:
RandomStringGenerator randomStringGenerator =
new RandomStringGenerator.Builder()
.withinRange('0', 'z')
.filteredBy(CharacterPredicates.LETTERS, CharacterPredicates.DIGITS)
.build();
randomStringGenerator.generate(12); // toUpperCase() if you want
自Apache Commons Lang 3.6以来,RandomStringUtils已被弃用。