Java中生成随机字母数字字符串的方法

Java中生成随机字母数字字符串的方法

技术背景

在Java开发中,经常会有生成随机字母数字字符串的需求,比如作为唯一的会话/密钥标识符。对于一些简单的应用场景,需要生成的字符串在一定数量(如500K+)内“大概率”保持唯一。同时,不同的应用场景对字符串的安全性、长度、字符集等方面有不同的要求。

实现步骤

方法一:自定义类实现

可以创建一个自定义类来实现随机字符串的生成,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
import java.util.Objects;
import java.util.Random;
import java.util.Locale;

public class RandomString {

/**
* Generate a random string.
*/
public String nextString() {
for (int idx = 0; idx < buf.length; ++idx)
buf[idx] = symbols[random.nextInt(symbols.length)];
return new String(buf);
}

public static final String upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

public static final String lower = upper.toLowerCase(Locale.ROOT);

public static final String digits = "0123456789";

public static final String alphanum = upper + lower + digits;

private final Random random;

private final char[] symbols;

private final char[] buf;

public RandomString(int length, Random random, String symbols) {
if (length < 1) throw new IllegalArgumentException();
if (symbols.length() < 2) throw new IllegalArgumentException();
this.random = Objects.requireNonNull(random);
this.symbols = symbols.toCharArray();
this.buf = new char[length];
}

/**
* Create an alphanumeric string generator.
*/
public RandomString(int length, Random random) {
this(length, random, alphanum);
}

/**
* Create an alphanumeric strings from a secure generator.
*/
public RandomString(int length) {
this(length, new SecureRandom());
}

/**
* Create session identifiers.
*/
public RandomString() {
this(21);
}
}

使用示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import java.util.concurrent.ThreadLocalRandom;
import java.security.SecureRandom;

public class Main {
public static void main(String[] args) {
// 创建一个不安全的8字符标识符生成器
RandomString gen = new RandomString(8, ThreadLocalRandom.current());
System.out.println(gen.nextString());

// 创建一个安全的会话标识符生成器
RandomString session = new RandomString();
System.out.println(session.nextString());

// 创建一个易于阅读的代码生成器
String easy = RandomString.digits + "ACEFGHJKLMNPQRUVWXYabcdefhijkprstuvwx";
RandomString tickets = new RandomString(23, new SecureRandom(), easy);
System.out.println(tickets.nextString());
}
}

方法二:使用UUID类

Java的UUID类可以方便地生成随机字符串,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
import java.util.UUID;

public class randomStringGenerator {
public static void main(String[] args) {
System.out.println(generateString());
}

public static String generateString() {
String uuid = UUID.randomUUID().toString();
return "uuid = " + uuid.replace("-", "");
}
}

方法三:简单字符拼接实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import java.security.SecureRandom;

public class RandomStringSimple {
static final String AB = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
static SecureRandom rnd = new SecureRandom();

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

public static void main(String[] args) {
System.out.println(randomString(12));
}
}

核心代码

自定义类实现核心代码

1
2
3
for (int idx = 0; idx < buf.length; ++idx)
buf[idx] = symbols[random.nextInt(symbols.length)];
return new String(buf);

UUID类实现核心代码

1
2
String uuid = UUID.randomUUID().toString();
return uuid.replace("-", "");

简单字符拼接实现核心代码

1
2
3
4
StringBuilder sb = new StringBuilder(len);
for (int i = 0; i < len; i++)
sb.append(AB.charAt(rnd.nextInt(AB.length())));
return sb.toString();

最佳实践

  • 安全性:如果生成的字符串用于安全敏感场景,如会话标识符,建议使用SecureRandom类来保证随机性和安全性。
  • 长度选择:根据具体需求选择合适的字符串长度,考虑“生日悖论”,确保在预期的生成数量内碰撞概率足够低。
  • 字符集选择:根据应用场景选择合适的字符集,避免使用可能引起编码问题的字符。

常见问题

  • 碰撞问题:当生成的字符串数量较多时,可能会出现碰撞(即生成相同的字符串)。可以通过增加字符串长度或使用更大的字符集来降低碰撞概率。
  • 性能问题SecureRandom类的初始化和使用可能会带来一定的性能开销,尤其是在需要大量生成随机字符串的场景下。可以考虑缓存SecureRandom实例以提高性能。
  • URL安全问题:如果生成的字符串将用于URL中,需要确保字符集不包含可能导致URL编码问题的字符,或者使用URL安全的编码方式。

Java中生成随机字母数字字符串的方法
https://119291.xyz/posts/2025-04-24.java-random-alphanumeric-string-generation/
作者
ww
发布于
2025年4月24日
许可协议