Java在包java.secure.random中提供了加密安全的随机数生成器。
如果考虑RNG的播种和循环重新实例化,是否可以使用此数字生成器?还是可以按原样使用数字生成器?
有没有人体验过这个发电机?
编辑 :要求是:
a)统计上独立
b)在其范围内公平分配(在统计上预期的范围内)
c)通过各种公认的统计测试
d)加密强度高。
就像其他人所说的那样,安全的RNG可能具有有限的吞吐量。为了减轻这种情况,您可以通过播种CPRNG来扩展安全性随机性,也可以尝试优化比特流的使用。
例如,要随机播放一组卡,您只需要226位,但是幼稚的算法(调用nextInt(n)每张卡)可能会使用1600或3200位,这浪费了85%的熵,并使延迟的敏感性提高了7倍。
nextInt(n)
对于这种情况,我认为Jacques医生方法是合适的。
为此,下面是一些性能分析,这些性能分析是针对越来越昂贵的熵源(还包含代码)进行的:
位循环用于缩放随机数生成器
我倾向于有效使用而不是扩展,因为我认为证明可信赖的熵流的有效消费者的公平性要比使用种子良好的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版本替换了它。设定牌洗牌时间范围的值显示,速度几乎提高了6倍SecureRandom.nextInt(n)。
SecureRandom.nextInt(n)
我以前的代码版本(仅2倍加速)假定SecureRandom.next(b)效率很高,但事实证明,调用是在丢弃熵并将整个循环拖到下面。此版本管理自己的分块。
SecureRandom.next(b)