我一直在寻找一种简单的Java算法来生成伪随机字母数字字符串。在我的情况下,它将被用作唯一的会话/密钥标识符,“很可能”在超过50万代的时间内是唯一的(我的需求实际上不需要更复杂的东西)。

理想情况下,我可以根据我的独特性需求指定长度。例如,生成的长度为12的字符串可能看起来像“AEYGF7K0DM1X”。


当前回答

我正在使用Apache Commons的库生成一个字母数字字符串:

import org.apache.commons.lang3.RandomStringUtils;

String keyLength = 20;
RandomStringUtils.randomAlphanumeric(keylength);

它又快又简单!

其他回答

此外,您可以通过ASCII表中的数据生成任何小写或大写字母,甚至特殊字符。例如,生成从A(DEC 65)到Z(DEC 90)的大写字母:

String generateRandomStr(int min, int max, int size) {
    String result = "";
    for (int i = 0; i < size; i++) {
        result += String.valueOf((char)(new Random().nextInt((max - min) + 1) + min));
    }
    return result;
}

generateRandomStr(65、90、100)的生成输出;:

TVLPFQJCYFXQDCQSLKUKKILKKHAUFYEXLUQFHDWNMRBIRRRWNXNNZQTINZPCTKLHGHVYWRKEOYNSOFPZBGEECFMCOKWHLHCEWLDZ

这里有一个简单的一行代码,使用UUID作为字符基础,可以指定(几乎)任何长度。(是的,我知道以前有人建议使用UUID。)

public static String randString(int length) {
    return UUID.randomUUID().toString().replace("-", "").substring(0, Math.min(length, 32)) + (length > 32 ? randString(length - 32) : "");
}

我不太喜欢这些关于“简单”解决方案的答案: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("-", "")
public static String RandomAlphanum(int length)
{
    String charstring = "abcdefghijklmnopqrstuvwxyz0123456789";
    String randalphanum = "";
    double randroll;
    String randchar;
    for (double i = 0; i < length; i++)
    {
        randroll = Math.random();
        randchar = "";
        for (int j = 1; j <= 35; j++)
        {
            if (randroll <= (1.0 / 36.0 * j))
            {
                randchar = Character.toString(charstring.charAt(j - 1));
                break;
            }
        }
        randalphanum += randchar;
    }
    return randalphanum;
}

我使用Math.random()使用了一个非常原始的算法。为了增加随机性,可以直接实现util.Date类。尽管如此,它还是有效的。

如果您愿意使用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已被弃用。