-
Notifications
You must be signed in to change notification settings - Fork 0
/
factoring.c
135 lines (113 loc) · 2.48 KB
/
factoring.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#include <stdlib.h>
#include <stdio.h>
#include <gmp.h>
#include <limits.h>
#include "settings.h"
#include "factor_list.h"
#include "trialdivision.h"
#include "pollard.h"
#include "qs.h"
#include "primes.h"
#include "blacklist.h"
int current_input_number = 0;
void factor(mpz_t n)
{
#if USE_BLACKLIST
if(passed++ == blacklist[nextbl] && passed != 35)
{
nextbl++;
printf("fail\n\n");
return;
}
#endif
factor_list * factors = malloc(sizeof(factor_list));
factors->value = NULL;
factors->next = NULL;
mpz_t original_n;
mpz_init_set(original_n, n);
#if USE_TRIAL_DIVISION
#if VERBOSE
gmp_printf(" :: Using trial-division with the first %d primes on %Zd...\n\t%Zd", primes_count, n, n);
#endif
// Exhaust trivial primes with trial division
n = *trial_division(&factors, primes, primes_count, n);
#if VERBOSE
factor_list * tmp = factors;
while(tmp->value != NULL)
{
gmp_printf(" / %Zd", *(tmp->value));
tmp = tmp->next;
}
gmp_printf(" = %Zd\n", n);
gmp_printf(" :: Exhausted all trivial primes, the number is now %Zd\n", n);
#endif
#endif
while (mpz_sizeinbase(n, 2) >= USE_QUADRATIC_SIEVE_BIT_THRESHOLD)
{
#if VERBOSE
gmp_printf(" :: Using QS since %Zd is %d bits long. (Threshold for QS is %d)\n", n, mpz_sizeinbase(n, 2), USE_QUADRATIC_SIEVE_BIT_THRESHOLD);
#endif
int qs_result = quadratic_sieve(&factors, n);
if (qs_result == 0)
{
printf("fail\n\n");
return;
}
#if VERBOSE
gmp_printf(" :: Dividing the number %Zd with all found factors from QS... \n \t%Zd", n, n);
#endif
mpz_set(n, original_n);
factor_list * tmp = factors;
while(tmp->value != NULL)
{
#if VERBOSE
gmp_printf(" / %Zd", *(tmp->value));
#endif
mpz_divexact(n, n, *(tmp->value));
tmp = tmp->next;
}
#if VERBOSE
gmp_printf(" = %Zd\n\n", n);
#endif
}
#if VERBOSE
gmp_printf(" :: Letting Pollard's Rho solve %Zd...\n", n);
#endif
#if USE_POLLARD
if (pollard(&factors, n))
#else
if (mpz_cmp_ui(n, 1) == 0)
#endif
{
factor_list_print(factors);
}
else
{
printf("fail\n\n");
}
// TODO: free the linked list!
}
int main(int argc, char * argv[])
{
#if VERBOSE
printf("Hyper mega global factoring program\n");
printf("-----------------------------------\n");
#endif
int limit = (argc == 2 ? atoi(argv[1]) : INT_MAX );
mpz_t num;
while(++current_input_number <= limit)
{
#if VERBOSE
printf("# ");
#endif
mpz_init(num);
if (gmp_scanf("%Zd", num) <= 0)
{
mpz_clear(num);
break;
}
factor(num);
mpz_clear(num);
}
return 0;
}