diff --git a/ChangeLog b/ChangeLog index b29c3e6..3baee2b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -25,6 +25,9 @@ Version NEXT SConstruct: declare CPP constant SIZEOF_LONG randomcheck: use SIZEOF_LONG for grabing highest bits from long() randomcheck: print more fraction digits in report + randomcheck: ability to run group tests with different seeds + this will more balance results to be less initial seed + dependant. classic fsp algo seems to produce best results. Version 2.8.1b29 - 24 Aug 2019 added scons command line argument without-fspscan=yes for building diff --git a/tests/randomcheck.c b/tests/randomcheck.c index 78b45ae..4d3f982 100644 --- a/tests/randomcheck.c +++ b/tests/randomcheck.c @@ -4,8 +4,10 @@ #include "my-string.h" #include +static int group[4]; static int bitcount[16]; static int rounds; +static int groups; static int result; #define MAX_WORST_ALLOWED 0.1f @@ -76,17 +78,16 @@ static void run_randomtest( unsigned short (*keygen)(void) ) } } -static float print_bitcount(void) +static void print_bitcount(void) { int i; - float worst; - float ratio; + float worst = 0; printf("Set ratio: "); - worst=0; for(i=0;i<16;i++) { + float ratio; float delta; ratio=(float)bitcount[i]/rounds; delta = fabs(ratio-0.5f); @@ -96,42 +97,119 @@ static float print_bitcount(void) } printf(" Worst: %.4f\n", worst); if(worst>MAX_WORST_ALLOWED) result++; +} + +static float worst_bitcount(void) +{ + int i; + float worst = 0.0f; + + for(i=0;i<16;i++) + { + float ratio; + float delta; + ratio=(float)bitcount[i]/rounds; + delta = fabs(ratio-0.5f); + if(delta > worst) + worst=delta; + } return worst; } +static void run_one(void) +{ + float worst[4]; + memset(worst, 0, sizeof(worst)); + + run_randomtest(classic); + worst[0] = worst_bitcount(); + + run_randomtest(simple); + worst[1] = worst_bitcount(); + + run_randomtest(simple2); + worst[2] = worst_bitcount(); + + run_randomtest(nr); + worst[3] = worst_bitcount(); + + /* fimd the best algo */ + float minValue = worst[0]; + int minIndex = 0; + + for (int i = 1; i < 4; i++) + { + if (worst[i] < minValue) + { + minValue = worst[i]; + minIndex = i; + } + } + + group[minIndex] += 1; +} + +static void seed_rng(void) +{ +#ifdef HAVE_SRANDOMDEV + srandomdev(); +#endif +} int main(int argc,const char *argv[]) { /* 100k rounds by default */ rounds=100000; + /* 20 groups by default */ + groups=20; + + /* override counts from command line */ + if(argc>2) + { + groups=atoi(argv[2]); + } if(argc>1) { rounds=atoi(argv[1]); } - printf("Running %d rounds.\n\n", rounds); + printf("Running %d groups of %d rounds.\n\n", groups, rounds); result=0; -#ifdef HAVE_SRANDOMDEV - srandomdev(); -#endif + memset(group, 0, sizeof(group)); - printf("Generator: classic\n"); - run_randomtest(classic); - print_bitcount(); + if ( groups == 1 ) + { + seed_rng(); + printf("Generator: classic\n"); + run_randomtest(classic); + print_bitcount(); - printf("Generator: simple\n"); - run_randomtest(simple); - print_bitcount(); + printf("Generator: simple (low bits)\n"); + run_randomtest(simple); + print_bitcount(); - printf("Generator: simple2\n"); - run_randomtest(simple2); - print_bitcount(); + printf("Generator: simple2 (high bits)\n"); + run_randomtest(simple2); + print_bitcount(); - result=0; - printf("Generator: Numerical Recipes\n"); - run_randomtest(nr); - print_bitcount(); + printf("Generator: Numerical Recipes\n"); + run_randomtest(nr); + print_bitcount(); + } else { + int i; + for (i=0; i< groups; i++) + { + seed_rng(); + run_one(); + } + + printf("Winning generators\n\n"); + printf("Generator: classic %d\n", group[0]); + printf("Generator: simple (low bits) %d\n", group[1]); + printf("Generator: simple2 (high bits) %d\n", group[2]); + printf("Generator: Numerical Recipes %d\n", group[3]); + } return result; }