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/