【问题标题】:Should SecureRandom be used as singleton or a new object should be created each time random number is generated?SecureRandom 应该用作单例还是应该在每次生成随机数时创建一个新对象?
【发布时间】:2020-02-20 08:24:38
【问题描述】:

我正在使用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);
    }
}

这个问题是在阅读了与“线性同余生成器的可预测性”相关的 this answer 之后提出的。

【问题讨论】:

  • 为什么投反对票?
  • 它不应该有所作为(尽管SecureRandom 的大部分内容是特定于平台的),但这并不重要,因为第一种方式是正确的方式,而第二种方式是非常错误的方式。
  • @Kayaman 如果它不应该有所作为,为什么第二个大错特错?
  • @FedericoklezCulloca 因为SecureRandom 是一个不必要地创建的昂贵对象,所以虽然它不应该影响可预测性(尽管它可能会耗尽熵,但不确定,guess not)它仍然是一个明显的使用长寿对象的错误方法。

标签: java random secure-random


【解决方案1】:

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

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

如果熵用完了,SecureRandom 创建可能会阻塞在系统调用中……等待……等待……收获更多熵。

在可预测性方面有什么不同吗?

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

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

这个问题是在阅读了...“线性同余生成器的可预测性”之后提出的。

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-01-16
    • 1970-01-01
    • 1970-01-01
    • 2012-07-07
    • 1970-01-01
    • 2019-09-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多