示例#1
0
文件: main.c 项目: mharrys/factor
int
main(int argc, char **argv)
{
	char line[INTEGER_LIMIT];
	if (argc > 1)
		strncpy(&line[0], argv[1], INTEGER_LIMIT);
	else if (scanf("%s\n", &line[0]) != 1) {
		fprintf(stderr, "factor: unable to read number from stdin\n");
		return 1;
	}

	mpz_t n;
	mpz_init(n);

	if (mpz_set_str(n, &line[0], 0) == -1 || mpz_cmp_ui(n, 1) < 0) {
		fprintf(stderr, "factor: input must be a positive integer\n");
		mpz_clear(n);
		return 1;
	}

	if (mpz_cmp_ui(n, 1) == 0 || mpz_probab_prime_p(n, MILLERRABIN_REPEATS) > 0) {
		gmp_printf("%Zd: %Zd\n", n, n);
		mpz_clear(n);
		return 0;
	}

	mpz_t t;
	mpz_init(t);
	mpz_sqrt(t, n);

	struct factors *f = factors_create();
	struct prime_sieve *ps = prime_sieve_create(MIN(TRIALDIVISION_LIMIT, mpz_get_ui(t)));

	if (mpz_perfect_square_p(n)) {
		factors_push(f, t);
		factors_push(f, t);
	} else {
		mpz_set(t, n);
		factors_push(f, t);
	}

	/* run trial division to find find small factors */
	while (factors_remove_composite(f, t) && trial_division(t, f, ps));
	prime_sieve_destroy(ps);

	/* run quadratic sieve until factorized into only prime numbers */
	while (factors_remove_composite(f, t) && quadratic_sieve(t, f, QUADRATIC_SIEVE_SIZE));

	factors_sort(f);
	print_result(n, f);

	mpz_clears(n, t, NULL);
	factors_destroy(f);

	return 0;
}
示例#2
0
int main()
{
    int limit = 60;
    primeWithin(primes, limit);    
    primes.push_back(-1);
    sort(primes.begin(), primes.end());
    //this prime vector is  special, -1 included in the first place, 
    //when primes are used as regular prime vector start from 1
    generate_congmap(congmap, limit);
    i64 num=600851475143LL;
    vector<i64> vresult;
    vresult = quadratic_sieve(num);
    for(unsigned int i = 0; i < vresult.size(); ++i)
        printf("%lld\n", vresult[i]);
}
示例#3
0
int main() {
	srand(1337);

	// The primes we will perform trial division with on small integers.
	std::vector<uint32_t> primes;

	// Generate the trial division primes using a simple sieve.
	{
		uint32_t max = (uint32_t)ceil(sqrt(TRIAL_BOUND)) + 1;
		char *sieve = new char[max];
		memset(sieve, 1, max);
		for(uint32_t p = 2; p < max; ++p) {
			if(!sieve[p])
				continue;
			primes.push_back(p);
			for(uint32_t i = p; i < max; i += p)
				sieve[i] = 0;
		}
		delete[] sieve;
	}

	mpz_class N;

	// Read numbers to factor from stdin until EOF.
	while(std::cin >> N) {
		// This quadratic sieve implementation is designed to factor numbers no larger than 100 bits.
		if(mpz_sizeinbase(N.get_mpz_t(), 2) > 100) {
			std::cerr << N << " is too large\n" << std::endl;
			continue;
		}

		std::stack<mpz_class> factors;

		factors.push(N);

		while(!factors.empty()) {
			mpz_class factor = factors.top();
			factors.pop();

			// If the factor is prime, print it.
			if(mpz_probab_prime_p(factor.get_mpz_t(), 10)) {
				std::cout << factor << std::endl;
				continue;

			// Run trial division if factor is small.
			} else if(factor < TRIAL_BOUND) {
				uint32_t f = factor.get_ui();
				for(uint32_t p = 0; p < primes.size(); ++p) {
					if(f % primes[p] == 0) {
						factors.push(primes[p]);
						factors.push(factor / primes[p]);
						break;
					}
				}

			} else {
				// Before we run quadratic sieve, check for small factors.
				bool found_factor = false;
				for(uint32_t p = 0; p < primes.size(); ++p) {
					if(mpz_divisible_ui_p(factor.get_mpz_t(), primes[p])) {
						factors.push(primes[p]);
						factors.push(factor / primes[p]);
						found_factor = true;
						break;
					}
				}
				if(found_factor)
					continue;

				// Quadratic sieve doesn't handle perferct powers very well, handle those separately.
				if(mpz_perfect_power_p(factor.get_mpz_t())) {
					mpz_class root, rem;

					// Check root remainders up half of the amount of bits in factor.
					uint32_t max = mpz_sizeinbase(factor.get_mpz_t(), 2) / 2;
					for(uint32_t n = 2; n < max; ++n) {
						mpz_rootrem(root.get_mpz_t(), rem.get_mpz_t(), factor.get_mpz_t(), n);
						if(rem == 0) {
							// Push the n root factors.
							for(uint32_t i = 0; i < n; ++i)
								factors.push(root);
							break;
						}
					}

				} else {
					mpz_class f = quadratic_sieve(factor);

					factors.push(f);
					factors.push(factor / f);
				}
			}
		}

		std::cout << std::endl;
	}

	return 0;
}