SecureRandom 应该用作单例还是每次生成随机数时都应该创建一个新对象?

Should SecureRandom be used as singleton or a new object should be created each time random number is generated?

我正在使用 SecureRandom 生成随机数。

如果 SecureRandom 对象是单例或每次生成随机数时都创建一个新对象,那么对于生成的下一个数字的可预测性有什么不同吗?

单例:

public RequestIdGenerator {
    private static SecureRandom secureRandom = new SecureRandom();

    public static int generateRequestId() {
        secureRandom.nextInt(100_000_000);
    }
}

对比

每次生成随机数的新对象:

public RequestIdGenerator {

    public static int generateRequestId() {
        new SecureRandom().nextInt(100_000_000);
    }
}

阅读有关 'Predictability of Linear Congruential Generators' 的 this answer 后出现了这个问题。

Should SecureRandom be used as singleton or a new object should be created each time random number is generated?

您不应创建很多 SecureRandom 个实例。它很昂贵,并且容易耗尽系统的熵源(随机性)。

如果你 运行 没有熵,SecureRandom 创建很容易在系统调用中阻塞......等待......等待......更多的熵被收集。

Does it make any difference with respect to predictability.

它不应该对可预测性产生任何影响。如果您将种子 SecureRandom 视为黑盒,则应该无法预测下一个数字 除非 您知道生成器的种子和之前的历史记录。

需要注意的是,有缺陷的实施 安全随机数生成器实际上可能并不安全。 (但不利的一面是,您用来生成种子的熵可能不像您想象的那样随机……也不是。)

This question arose after reading about ... 'Predictability of Linear Congruential Generators'.

LCG 从根本上说是不安全的。您不能将一个用于 SecureRandom 实施。

javadoc 包括对任何 SecureRandom 实施要求的引用。如果您有实际问题,请阅读参考资料。