1 |
//$Header$ |
2 |
//******************************************************************************** |
3 |
//Copyright (c) 2003, 2018 David T. Ashley. |
4 |
//******************************************************************************** |
5 |
//This file is part of "arith_large_cgi", a program that is designed to be |
6 |
//invoked by a PHP script as part of serving a web page that performs |
7 |
//calculations involving large integers. (A secondary compiled program is |
8 |
//used because a compiled program can perform certain calculation-intensive |
9 |
//tasks far more efficiently than a PHP script.) This program is provided by |
10 |
//David T. Ashley (dashley@gmail.com) under the MIT License (reproduced |
11 |
//immediately below). |
12 |
//******************************************************************************** |
13 |
//Permission is hereby granted, free of charge, to any person obtaining a copy |
14 |
//of this software and associated documentation files (the "Software"), to deal |
15 |
//in the Software without restriction, including without limitation the rights |
16 |
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
17 |
//copies of the Software, and to permit persons to whom the Software is |
18 |
//furnished to do so, subject to the following conditions: |
19 |
// |
20 |
//The above copyright notice and this permission notice shall be included in all |
21 |
//copies or substantial portions of the Software. |
22 |
// |
23 |
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
24 |
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
25 |
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
26 |
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
27 |
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
28 |
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
29 |
//SOFTWARE. |
30 |
//******************************************************************************** |
31 |
// |
32 |
//This module uses the GMP libary function: |
33 |
// |
34 |
// mpz_probab_prime_p() |
35 |
// |
36 |
//To make a probabilistic assessment of whether an integer is most likely |
37 |
//prime, definitely composite, etc. This module is just a direct interface |
38 |
//to the GMP function cited above. |
39 |
// |
40 |
//INPUT PARAMETERS |
41 |
//---------------- |
42 |
//The subfunction accepts two parameters, the integers whose primality is to be |
43 |
//assessed, and the number of reps (passed directly to the GMP function). |
44 |
//Naturally, the integers should be positive. Invalid integers are assigned |
45 |
//defaults. It is the responsibility of the calling script to do whatever |
46 |
//sanity checking is desired. |
47 |
// |
48 |
//OUTPUT RESULTS |
49 |
//-------------- |
50 |
//The notation below gives the outputs of the program. In some cases, [i] notation |
51 |
//is used to indicate line numbers. |
52 |
// |
53 |
//[01] An overall success or failure code for the operation. Valid responses |
54 |
// are: |
55 |
// S : Success (for this subfunction, the only possible outcome). |
56 |
// |
57 |
//[02] The fully normalized first integer entered. This means it has been |
58 |
// stripped of all weird characters, etc., and also perhaps assigned |
59 |
// a default value if the original parameter wasn't acceptable. |
60 |
// This can be used by the PHP script to repopulate form boxes. |
61 |
//[03] The fully normalized second integer entered. |
62 |
//[04] The output from the GMP function. Semantics are: |
63 |
// 2 -- definitely prime. |
64 |
// 1 -- probably prime. |
65 |
// 0 -- definitely composite. |
66 |
//[05] "S", indicating success. |
67 |
// |
68 |
//Note that this subfunction will always return exactly five lines, |
69 |
//and the first and last line will be "S". |
70 |
// |
71 |
//The return value (exit code) from this subfunction is always 0. |
72 |
// |
73 |
|
74 |
#define MODULE_SUBFUNC_GMP_PROB_PRIME |
75 |
|
76 |
#include <assert.h> |
77 |
#include <ctype.h> |
78 |
#include <stddef.h> |
79 |
#include <stdio.h> |
80 |
#include <stdlib.h> |
81 |
#include <string.h> |
82 |
#include <time.h> |
83 |
|
84 |
#include <gmp.h> |
85 |
|
86 |
#include "auxfuncs.h" |
87 |
#include "subfunc_gmp_prob_prime.h" |
88 |
|
89 |
|
90 |
int SUBFUNC_GMP_PROB_PRIME_main(int argc, char *argv[]) |
91 |
{ |
92 |
//Normalized first and second parameters (the integers). |
93 |
char *arg1; |
94 |
char *arg2; |
95 |
|
96 |
//GMP types to maintain the algorithm. |
97 |
int nreps_native; |
98 |
mpz_t number_to_test, nreps_mpz; |
99 |
|
100 |
//Result from the GMP. |
101 |
int gmp_result; |
102 |
|
103 |
//There must be an acceptable number of command-line arguments. If not, |
104 |
//abort the progam with phony data. |
105 |
if (argc != 4) |
106 |
{ |
107 |
printf("S\n2\n5\n2\nS\n"); |
108 |
return(0); |
109 |
} |
110 |
|
111 |
//Copy the command-line arguments to a safe place where we can manipulate them. |
112 |
//Leave 2 characters of space in case we assign a "0". |
113 |
arg1 = (char *)malloc((AUXFUNCS_size_t_max(1, strlen(argv[2])) + 1) * sizeof(char)); |
114 |
arg2 = (char *)malloc((AUXFUNCS_size_t_max(1, strlen(argv[3])) + 1) * sizeof(char)); |
115 |
if ((arg1 == NULL) || (arg2 == NULL)) |
116 |
{ |
117 |
printf("S\n2\n5\n2\nS\n"); |
118 |
return(0); |
119 |
} |
120 |
strcpy(arg1, argv[2]); |
121 |
strcpy(arg2, argv[3]); |
122 |
|
123 |
//Strip all of the non-digit trash out of the arguments. |
124 |
AUXFUNCS_remove_non_digits(arg1); |
125 |
AUXFUNCS_remove_non_digits(arg2); |
126 |
|
127 |
//Remove all leading zeros from both arguments. |
128 |
AUXFUNCS_remove_leading_zeros(arg1); |
129 |
AUXFUNCS_remove_leading_zeros(arg2); |
130 |
|
131 |
//If either argument is zero length, fill it in with 0. |
132 |
if (!strlen(arg1)) |
133 |
strcpy(arg1, "0"); |
134 |
if (!strlen(arg2)) |
135 |
strcpy(arg2, "0"); |
136 |
|
137 |
//We are not allowed to have 0's in this function, so |
138 |
//abort on zeros. Also, we can't have 1 for a number to check, |
139 |
//as 1 is neither prime nor composite. |
140 |
if ((!strcmp(arg1, "0")) || (!strcmp(arg2, "0")) || (!strcmp(arg1, "1"))) |
141 |
{ |
142 |
printf("S\n2\n5\n2\nS\n"); |
143 |
return(0); |
144 |
} |
145 |
|
146 |
//If either argument exceeds 10000 digits, abort. |
147 |
if ((strlen(arg1)>10000) || (strlen(arg2) > 10000)) |
148 |
{ |
149 |
printf("S\n2\n5\n2\nS\n"); |
150 |
return(0); |
151 |
} |
152 |
|
153 |
//Initialize all of the GMP variables. |
154 |
mpz_init(number_to_test); |
155 |
mpz_init(nreps_mpz); |
156 |
|
157 |
//Assign a and b to initial values. |
158 |
mpz_set_str(number_to_test, arg1, 10); |
159 |
mpz_set_str(nreps_mpz, arg2, 10); |
160 |
|
161 |
//We don't want to allow any more than 5000 repetitions for that |
162 |
//parameter. So, if it is larger than 5000, whack it down. |
163 |
if (mpz_cmp_d(nreps_mpz, (double)5000) > 0) |
164 |
mpz_set_str(nreps_mpz, "5000", 10); |
165 |
|
166 |
//Extract the arbitrary length value of the number of reps into |
167 |
//a normal integer. |
168 |
nreps_native = mpz_get_si(nreps_mpz); |
169 |
|
170 |
//Run the GMP library function to guess at primality and get the result |
171 |
//back. |
172 |
gmp_result = mpz_probab_prime_p(number_to_test, nreps_native); |
173 |
|
174 |
//Now, write the output block. |
175 |
printf("S\n"); |
176 |
mpz_out_str(stdout, 10, number_to_test); |
177 |
printf("\n"); |
178 |
mpz_out_str(stdout, 10, nreps_mpz); |
179 |
printf("\n"); |
180 |
printf("%d\n", gmp_result); |
181 |
printf("S\n"); |
182 |
|
183 |
//Always return 0. |
184 |
return(0); |
185 |
} |
186 |
|
187 |
//******************************************************************************** |
188 |
// End of SUBFUNC_GMP_PROB_PRIME.C. |
189 |
//******************************************************************************** |