1.前言
近期看微信支付库,发现其随机数生成器使用的是SecureRandom,并非是经常使用的ThreadLocalRandom,具体代码如下所示:
/** 随机串生成工具 */
public class NonceUtil {
private NonceUtil() {}
private static final char[] SYMBOLS =
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
private static final SecureRandom random = new SecureRandom();
/**
* 使用SecureRandom生成随机串
*
* @param length 随机串长度
* @return nonce 随机串
*/
public static String createNonce(int length) {
char[] buf = new char[length];
for (int i = 0; i < length; ++i) {
buf[i] = SYMBOLS[random.nextInt(SYMBOLS.length)];
}
return new String(buf);
}
}
经过调验,得出了Random/ThreadLocalRandom/SecureRandom
的区别,将在下文进行阐述。
首先需要补充随机数概念:
伪随机数 (Pseudo-Random Number)
生成方式:使用确定性的算法生成,通常基于初始种子值(seed)。
特性:虽然看起来是随机的,但如果知道种子值和算法,可以预测后续的数值。
用途:适用于一般用途的随机数生成,如模拟、游戏、简单的随机选择等。
性能:生成速度快,计算开销小。
示例:Java 中的
Random
和ThreadLocalRandom
类。
安全随机数 (Secure Random Number)
生成方式:使用加密强度的算法生成,通常依赖于操作系统提供的熵源(如
/dev/urandom
)。特性:不可预测,即使知道部分输出或内部状态,也无法预测后续的数值。
用途:适用于安全敏感的应用,如密码学、密钥生成、令牌生成等。
性能:生成速度较慢,计算开销较大,但提供更高的安全性。
示例:Java 中的
SecureRandom
类。
2. 随机数生成器区别
SecureRandom
、ThreadLocalRandom
和 Random
是 Java 中用于生成随机数的三个类,它们有不同的用途和特性:
Random:
用途:用于生成伪随机数。
特性:基于线性同余生成器 (LCG) 算法,速度快,但不适用于安全敏感的应用。
线程安全:不是线程安全的,多线程环境下需要外部同步。
ThreadLocalRandom:
用途:用于多线程环境下生成伪随机数。
特性:每个线程都有自己的
Random
实例,避免了多线程竞争,提高了性能。线程安全:线程安全,不需要外部同步。
SecureRandom:
用途:用于生成安全的随机数,适用于加密等安全敏感的应用。
特性:使用加密强度的随机数生成算法,可能比
Random
慢,但更安全。线程安全:线程安全。
示例代码
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;
import java.security.SecureRandom;
public class RandomExample {
public static void main(String[] args) {
// Random example
Random random = new Random();
System.out.println("Random: " + random.nextInt());
// ThreadLocalRandom example
ThreadLocalRandom threadLocalRandom = ThreadLocalRandom.current();
System.out.println("ThreadLocalRandom: " + threadLocalRandom.nextInt());
// SecureRandom example
SecureRandom secureRandom = new SecureRandom();
System.out.println("SecureRandom: " + secureRandom.nextInt());
}
}
3. 总结
使用
Random
进行一般的随机数生成。使用
ThreadLocalRandom
在多线程环境中生成随机数。使用
SecureRandom
在需要安全随机数的场景中。