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

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


当前回答

在一行中:

Long.toHexString(Double.doubleToLongBits(Math.random()));

来源:Java-生成随机字符串

其他回答

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类。尽管如此,它还是有效的。

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;
}

您可以在没有外部库的情况下在一行中完成此操作。

int length = 12;
String randomString = new Random().ints(48, 122).filter(i -> (i < 58 || i > 64) && (i < 91 || i > 96)).limit(length).collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append).toString();
System.out.print(randomString);

我将长度分隔成一个参数,并添加了一行以打印结果。

此代码创建一个以字母数字ascii范围为界的随机整数流。然后它过滤掉一些符号,因为字母数字范围不是连续的。然后它限制长度并将结果收集到字符串中。

因为这种方法丢弃了它生成的大约20%的数字/字符(因为它们是符号),所以对性能的影响很小。

我不觉得它特别可读,但我认为没有人在一行中提出过本机Java解决方案。

我开发了一个应用程序,为我的项目开发一个自动生成的字母数字字符串。在这个字符串中,前三个字符是字母,后七个字符是整数。

public class AlphaNumericGenerator {

    public static void main(String[] args) {
        java.util.Random r = new java.util.Random();
        int i = 1, n = 0;
        char c;
        String str = "";
        for (int t = 0; t < 3; t++) {
            while (true) {
                i = r.nextInt(10);
                if (i > 5 && i < 10) {

                    if (i == 9) {
                        i = 90;
                        n = 90;
                        break;
                    }
                    if (i != 90) {
                        n = i * 10 + r.nextInt(10);
                        while (n < 65) {
                            n = i * 10 + r.nextInt(10);
                        }
                    }
                    break;
                }
            }
            c = (char)n;

            str = String.valueOf(c) + str;
        }

        while(true){
            i = r.nextInt(10000000);
            if(i > 999999)
                break;
        }
        str = str + i;
        System.out.println(str);
    }
}

我找到了生成随机十六进制编码字符串的解决方案。所提供的单元测试似乎符合我的主要用例。虽然,它比提供的一些其他答案稍微复杂一些。

/**
 * Generate a random hex encoded string token of the specified length
 *  
 * @param length
 * @return random hex string
 */
public static synchronized String generateUniqueToken(Integer length){ 
    byte random[] = new byte[length];
    Random randomGenerator = new Random();
    StringBuffer buffer = new StringBuffer();

    randomGenerator.nextBytes(random);

    for (int j = 0; j < random.length; j++) {
        byte b1 = (byte) ((random[j] & 0xf0) >> 4);
        byte b2 = (byte) (random[j] & 0x0f);
        if (b1 < 10)
            buffer.append((char) ('0' + b1));
        else
            buffer.append((char) ('A' + (b1 - 10)));
        if (b2 < 10)
            buffer.append((char) ('0' + b2));
        else
            buffer.append((char) ('A' + (b2 - 10)));
    }
    return (buffer.toString());
}

@Test
public void testGenerateUniqueToken(){
    Set set = new HashSet();
    String token = null;
    int size = 16;

    /* Seems like we should be able to generate 500K tokens 
     * without a duplicate 
     */
    for (int i=0; i<500000; i++){
        token = Utility.generateUniqueToken(size);

        if (token.length() != size * 2){
            fail("Incorrect length");
        } else if (set.contains(token)) {
            fail("Duplicate token generated");
        } else{
            set.add(token);
        }
    }
}