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

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


当前回答

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

其他回答

public static String getRandomString(int length)
{
    String randomStr = UUID.randomUUID().toString();
    while(randomStr.length() < length) {
        randomStr += UUID.randomUUID().toString();
    }
    return randomStr.substring(0, length);
}
import java.util.*;
import javax.swing.*;

public class alphanumeric {
    public static void main(String args[]) {
        String nval, lenval;
        int n, len;

        nval = JOptionPane.showInputDialog("Enter number of codes you require: ");
        n = Integer.parseInt(nval);

        lenval = JOptionPane.showInputDialog("Enter code length you require: ");
        len = Integer.parseInt(lenval);

        find(n, len);
    }

    public static void find(int n, int length) {
        String str1 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        StringBuilder sb = new StringBuilder(length);
        Random r = new Random();

        System.out.println("\n\t Unique codes are \n\n");
        for(int i=0; i<n; i++) {
            for(int j=0; j<length; j++) {
                sb.append(str1.charAt(r.nextInt(str1.length())));
            }
            System.out.println("  " + sb.toString());
            sb.delete(0, length);
        }
    }
}

此外,您可以通过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

我不太喜欢这些关于“简单”解决方案的答案: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("-", "")

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

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解决方案。