如何对伪随机数发生器进行单元测试?

问题描述 投票:31回答:13

我有一个伪随机数生成器(PRNG)类,我想进行单元测试。有两种方法:

  1. 编写一个测试用例,其中包含大量样本并测试它们是否正确分布。这种方法可能会导致测试用例的执行时间相当长;
  2. 手动计算一小部分样本,并验证PRNG算法是否重现它。这种方法可能导致在不被注意的情况下生成非随机序列;

我会说第一种方法不是真正的单元测试,因为它不执行发生器的白盒测试,但另一方面它正确地测试了类的责任。第二种方法更像是一个真正的单元测试,侧重于算法,但它没有提供足够的证据来证明该类是否履行其职责。

您更喜欢哪种方法?为什么?


unit-testing random
13个回答
30
投票

获得相同PRNG算法的另一个实现,基于已知种子生成少量冗长的测试用例,并验证您的算法实现是否与其他人的实现相匹配。您测试的数据越多,它的可能性就越大。如果您想要认真,请研究如何对算法进行FIPS验证。

没有必要测试输出是否是随机的,因为其他人对算法的研究比你能够再现的更多。

如果您已经发明了自己的PRNG算法,那么您就会遇到一个相当不同的问题,因为除了测试代码之外,您还需要测试新算法。有很多事情要做 - 我认为最重要的是对输出的统计测试,以及其他密码学家的同行评审。但是,基本上,如果你设计的PRNG算法没有足够的知识来知道如何测试它,那么它将是垃圾。


0
投票

回到学校,我正在为模拟任务开发一个随机数生成器,并且需要一些方法来识别非随机性。

我有一个明智的想法,即取两个随机数并绘制它们(x,y)。令人惊讶的是人类大脑如何检测非随机模式。 (“随机模式”是矛盾的。)

我调整了PRNG以去除图表上出现的条纹和星暴,然后绘制(log(x),log(y))以获得全新视角并重复该过程。

后来,我被迫采取统计数据,并了解到你可以做奇怪的数学来量化随机性。



0
投票

一种方法是将其输出管道传输到PractRand

如果PractRand说PRNG的输出没问题,PRNG真的可以吗?我没有资格判断,但我能说的是,PRNG足够严格,认为我在文献或网上找到的各种LFSR和xor-shift算法的输出都不令人满意,并认为输出正常RP布伦特的xorgens。


-1
投票

除非您正在实施给定的PNRG算法,否则无法判断数字是否是随机的,这就是随机性的本质。是的,平均值,因为你的数字生成器向无穷大方向走,它会均匀,但你不会测试无数次的迭代。

如果您正在实施已知算法,请检查前几千个数字是否与给定一组种子时提供的结果相匹配。因为可能的种子数量是无限的,所以无法确定。

你甚至无法在数学上证明一系列数字是随机的......

XKCD

迪尔伯特

得到修改......


13
投票

为了测试PRNG,我会使用ENT这是一套统计测试,可以告诉你PRNG的表现如何。我想这是方法1。


5
投票

我想最终你会想要两个测试 - 因为你想确保以下两个都成立:

(1)数字分布正确,(2)特定算法按预期工作。

也许第一次测试只能偶尔运行,而第二次测试可能用于检查任何代码更改是否都没有破坏算法。


3
投票

我相信你的第一点(#1)更多地测试生成的随机数的质量,这取决于所使用的算法。第二点(#2)更多地测试算法的实现。如果您设计了算法,则两个测试都很重要。如果您实现了演示性能的算法,那么#2就足够了。虽然,我可能会测试多个种子以及使用某些特定发生器结构知识产生的序列。


3
投票

伪随机数发生器中的“随机性”通常表示为数字重复之前的平均迭代次数。有许多算法具有不同的“随机性”和性能。 Random.org对他们的算法进行了一些分析。查看页面中间的图片。在静态图像中很容易看出两种算法的随机性。

PRNG的一个特征(真正的特征,而不是伪装成特征的bug)是可预测的。对于给定的种子,应该产生相同的数字序列。这对于使用随机(也称为随机)方法的测试和调试程序来说非常重要和必要。

数字序列应接近某个统计分布。通过生成一个大序列(比如10 ^ 6个数字)来测试您的PRNG,并对序列进行多次统计测试,特别是Chi-Squared测试(如果分布正常)。制作样本的直方图,看看它是否符合预期。

如果您控制种子的设置方式,则每次生成的序列应该相同,这适合进行白盒测试。在进行测试时,通过在收集样品之前运行100次左右来“预热”发生器也是一个好主意。


3
投票

这是一个CodeProject article,其中包括Donald Knuth的第2卷“Seminumerical Algorithms”中提到的Kolmogorov-Smirnov检验的实现。正如上面提到的InSciTek Jeff,有两个问题:测试算法和测试算法的实现。 K-S测试可能会在实现中发现错误,并且它是测试算法本身质量的良好开端。


2
投票

Plesae要注意:如果你'发明了'你的PRNG,你可能会错误地产生一些不太理想的分布。对于你的发电机是如何随机的基本测试是卡方检验


2
投票

您可能会发现对this question的一些回复非常有用。

基本上,你无法“证明”RNG是随机的,但你可以进行各种测试以提高你的信心。这些测试的复杂性各不相同Diehard是全面的,但它并没有真正提供是/否答案,更像是几百个“maybes”。在光谱的另一端,生成一系列值(至少10,000)非常简单,然后检查平均值和标准偏差/方差是否为as expected


0
投票

严格来说,没有办法测试随机发生器是否真的是随机的:-)第一种方法可以让你知道它是否能够仅仅针对固定数量的样本进行适当的分配,无论这个数量多大。第二种方法可以支持知识,它的行为就像一个algorythm,但同样适用于固定数量的样本。

你能做的最好 - 两者同时使用。

© www.soinside.com 2019 - 2024. All rights reserved.