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

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


当前回答

使用美元应简单如下:

// "0123456789" + "ABCDE...Z"
String validCharacters = $('0', '9').join() + $('A', 'Z').join();

String randomString(int length) {
    return $(validCharacters).shuffle().slice(length).toString();
}

@Test
public void buildFiveRandomStrings() {
    for (int i : $(5)) {
        System.out.println(randomString(12));
    }
}

它输出的内容如下:

DKL1SBH9UJWC
JH7P0IT21EA5
5DTI72EO6SFU
HQUMJTEBNF7Y
1HCR6SKYWGT7

其他回答

令人惊讶的是,这里没有人建议,但:

import java.util.UUID

UUID.randomUUID().toString();

容易的

这样做的好处是UUID很好、很长,并且保证几乎不可能发生冲突。

维基百科对此有很好的解释:

“……只有在未来100年内每秒生成10亿个UUID之后,仅创建一个重复的概率才会达到50%。”

前四位是版本类型,两位是变体,因此您可以得到122位随机数。因此,如果需要,可以从末尾截断以减小UUID的大小。这是不推荐的,但你仍然有大量的随机性,足以让你的500k记录变得容易。

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

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

Java 8中的另一种选择是:

static final Random random = new Random(); // Or SecureRandom
static final int startChar = (int) '!';
static final int endChar = (int) '~';

static String randomString(final int maxLength) {
  final int length = random.nextInt(maxLength + 1);
  return random.ints(length, startChar, endChar + 1)
        .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append)
        .toString();
}

我认为这是这里最小的解决方案,或者几乎是最小的方案之一:

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