Пример #1
0
int
randlcg_selftest()
{
    unsigned i;
    int is_success = 0;
    uint64_t m, a, c;


    m = 3015 * 3;

    for (i=0; i<5; i++) {
        a = 0;
        c = 0;

        m += 10 + i;

        lcg_calculate_constants(m, &a, &c, 0);

        is_success = lcg_verify(a, c, m, m);

        if (!is_success) {
            fprintf(stderr, "LCG: randomization failed\n");
            return 1; /*fail*/
        }
    }

    return 0; /*success*/
}
Пример #2
0
int
randlcg_selftest()
{

    int is_success;
    uint64_t m, a, c;


    m = 3015 * 3;
    a = 0;
    c = 0;

    lcg_calculate_constants(m, &a, &c, 0);

    is_success = lcg_verify(a, c, m, m);

    if (!is_success) {
        fprintf(stderr, "LCG: randomization failed\n");
        return 1; /*fail*/
    } else {
        return 0; /*success*/
    }
}
Пример #3
0
/****************************************************************************
 * Given a range, calculate some possible constants for the LCG algorithm
 * for randomizing the order of the array.
 * @parm m
 *      The range for which we'll be finding random numbers. If we are
 *      looking for random numbers between [0..100), this number will
 *      be 100.
 * @parm a
 *      The LCG 'a' constant that will be the result of this function.
 * @param c
 *      The LCG 'c' constant that will be the result of this function. This
 *      should be set to 0 on the input to this function, or a suggested
 *      value.
 ****************************************************************************/
void
lcg_calculate_constants(uint64_t m, uint64_t *out_a, uint64_t *inout_c, int is_debug)
{
	uint64_t a;
	uint64_t c = *inout_c;
    double elapsed = 0.0; /* Benchmark of 'sieve' algorithm */
    PRIMEFACTORS factors; /* List of prime factors of 'm' */
	PRIMEFACTORS non_factors;
	unsigned i;

    /*
     * Find all the prime factors of the number. This step can take several
     * seconds for 48 bit numbers, which is why we benchmark how long it
     * takes.
     */
    sieve_prime_factors(m, factors, non_factors, &elapsed);
   
    /*
     * Calculate the 'a-1' constant. It must share all the prime factors
     * with the range, and if the range is a multiple of 4, must also
     * be a multiple of 4
     */
	if (factors[0] == m) {
		/* this number has no prime factors, so we can choose anything.
		 * Therefore, we are going to pick something at random */
		unsigned j;

		a = 1;
		for (j=0; non_factors[j] && j < 5; j++)
			a *= non_factors[j];
	} else {
		unsigned j;
		a = 1;
		for (i=0; factors[i]; i++)
			a = a * factors[i];
		if ((m % 4) == 0)
			a *= 2;
		
		for (j=0; j<0 && non_factors[j]; j++)
			a *= non_factors[j];
	}   
	a += 1;
   
    /*
     * Calculate the 'c' constant. It must have no prime factors in
     * common with the range.
     */
    if (c == 0)
        c = 2531011 ; /* something random */
    while (has_factors_in_common(c, factors))
        c++;

	if (is_debug) {
		/*
		 * print the results
		 */
		//printf("sizeof(int) = %llu-bits\n", (uint64_t)(sizeof(size_t)*8));
		printf("elapsed     = %5.3f-seconds\n", elapsed);
		printf("factors     = ");
		for (i=0; factors[i]; i++)
			printf("%llu ", factors[i]);
		printf("%s\n", factors[0]?"":"(none)");
		printf("m           = %-24llu (0x%llx)\n", m, m);
		printf("a           = %-24llu (0x%llx)\n", a, a);
		printf("c           = %-24llu (0x%llx)\n", c, c);
		printf("c%%m         = %-24llu (0x%llx)\n", c%m, c%m);
		printf("a%%m         = %-24llu (0x%llx)\n", a%m, a%m);
   
		if (m < 1000000000) {
			if (lcg_verify(a, c+1, m, 280))
				printf("verify      = success\n");
			else
				printf("verify      = failure\n");
		} else {
			printf("verify      = too big to check\n");
		}
       
   
		/*
		 * Print some first numbers. We use these to visually inspect whether
		 * the results are random or not.
		 */
		{
			unsigned count = 0;
			uint64_t x = 0;
			unsigned digits = count_digits(m);
       
			for (i=0; i<100 && i < m; i++) {
				x = lcg_rand(x, a, c, m);
				count += printf("%*llu ", digits, x);
				if (count >= 70) {
					count = 0;
					printf("\n");
				}
			}
			printf("\n");
		}
	}

	*out_a = a;
	*inout_c = c;
}