1. 伪随机数是周期性的,当它们足够多时,会重复数字序列。
2. 如果提供相同的算法和相同的种子值,将会得出完全一样的随机数序列。
3. 可以使用逆向工程,猜测算法与种子值,以便推算后面所有的随机数列。
即是说: 随机序列 = F(算法, 种子)
说到随机数的产生不得不提的是我们的随机数发生器往往是可以预测的。例如我们常用的随机rand 函数就是一个可以预测的。
int __cdecl rand (void )
{
return(((holdrand = holdrand * 214013L + 2531011L) >> 16) & 0x7fff);
}
在这个的背后其实是用的是Knuth pseudo-random number-generating 技术。Knuth 在这本书中"Seminumerical Algorithms," Vol. 2 of The Art of Computer Programming (Addison-Wesley, 1981)发表了这个算法。在实际的应用中我们如何产生适合应用的随机数是根据实际情况定的。比如我们在输入参数的安全性方面没有任何先验知识的情况下, 均匀分布是比较好的。在有先验知识或者是白盒测试的情况下正态分布可能是比较好的随机数分布。
这些分布的产 生一般都是先产生一个平均分布然后求对应分布的逆。网上能找到一堆伪随机数生成器的代码。下面就随便给一个。如何产生一个更好的伪随机数,以后再说 吧。
1double
AverageRandom(double min,double max) 2{ 3 4 int minInteger = (int)(min*10000); 5 int maxInteger = (int)(max*10000); 6 int randInteger = rand()*rand(); 7 int diffInteger = maxInteger - minInteger; 8 int resultInteger = randInteger % diffInteger + minInteger; 9 return resultInteger/10000.0; 10} 11double Normal(double x,double miu,double sigma) 12{ 13 return 1.0/sqrt(2*PI*sigma) * exp(-1*(x-miu)*(x-miu)/(2*sigma*sigma)); 14} 15double NormalRandom(double miu,double sigma,double min,double max) 16{ 17 double dResult; 18 double dScope; 19 double dNormal; 20 do 21 { 22 dResult = AverageRandom(min,max); 23 dScope = AverageRandom(0,Normal(miu, miu, sigma)); 24 dNormal = Normal(dResult, miu, sigma); 25 }while( dScope > dNormal); 26 return dResult; 27 28} 29 |
产生了随机数以后,参数进行适当的组合对对应的API函数进行测试,这样就能在数学上保证尽可能得覆盖到对应得参数空间。最大可能的找到 bug。
对于白盒测试来讲这种测试方法就更加适合,因为可以找一些比较合适的值作为初始值然后再产生随机的 参数,就可以更有针对性的找到bug。
其实这是一种测试-FUZZ testing 的基本思想.
a,b,c所组成的参数空间中的 一个 特殊的 取值范围内即当0<a<100 ,b=0,c=255这个特殊 空间的时候会触发一个特殊的bug.当然实际的情况要比这种情况复杂的多。但是总会隐藏着类似的bug.