java - java.secure.random 是博彩业的充分选择吗?

标签 java algorithm random prng

Java 在包 java.secure.random 中提供了一个加密安全的随机数生成器。

如果我考虑 RNG 的播种和循环重新实例化之类的事情,是否可以使用这个数字生成器?或者我可以“按原样”使用数字生成器吗?

有人用过这个发电机吗?

编辑:要求是:

a) 在统计上独立

b) 在他们的范围内公平分布(在统计预期范围内)

c) 通过各种公认的统计测试

d) 加密强度高。

最佳答案

正如其他人所说,安全 RNG 的吞吐量可能有限。为了减轻这个 您可以通过播种 CPRNG 来扩展安全随机性,或者您可以 尝试优化您对比特流的使用。

打个比方,要洗一副牌,你只需要 226 位,但是一个 naive 算法(为每张卡片调用 nextInt(n))可能会使用 1600 或 3200 比特,浪费了 85% 的熵,让你的易感性增加了七倍 延误。

对于这种情况我认为Doctor Jacques method将是合适的。

为此,这里有一些针对渐进式更多的性能分析 昂贵的熵源(也包含代码):

Bit recycling for scaling random number generators

我更倾向于有效使用而不是拉伸(stretch),因为我认为 证明有效消费者的公平性会容易得多 可信赖的熵流,比证明任何绘图方法的公平性 带有播种良好的 PRNG。


编辑2: 我不太了解 Java,但我把它放在一起:

public class MySecureRandom extends java.security.SecureRandom {
    private long m = 1;
    private long r = 0;

    @Override
    public final int nextInt(int n) {
        while (true) {
            if (m < 0x80000000L) {
                m <<= 32;
                r <<= 32;
                r += (long)next(32) - Integer.MIN_VALUE;
            }
            long q = m / n;
            if (r < n * q) {
                int x = (int)(r % n);
                m = q;
                r /= n;
                return x;
            }
            m -= n * q;
            r -= n * q;
        }
    }
}

这取消了贪婪的默认统一 [0,n-1] 生成器,并将其替换为修改后的 Doctor Jacques 版本。对卡片洗牌的值范围进行计时显示比 SecureRandom.nextInt(n) 几乎快 6 倍。

我之前的代码版本(仅 2 倍加速)假定 SecureRandom.next(b) 是高效的,但事实证明该调用正在丢弃熵并拖延整个循环。此版本管理自己的分块。

关于java - java.secure.random 是博彩业的充分选择吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17746768/

相关文章:

java - 将 CDI 装饰器添加到消息驱动 Bean

java - 对 Liquibase 脚本执行检查

java - 使用 Spring 进行 MongoDB 复制

css - 将样式设置为具有随机数的类名

java - 生成总和为 N 并遵循离散分布的随机数

c - 防止重复随机创建的相同数字

java - 如何让 Maven 忽略本地存储库版本的本地项目

algorithm - N个矩形交集

algorithm - 有多少间隔包含另一个间隔?

java - 生成从 1 到 2^k-1 的数字的二进制表示