Source: Internet
Author: User

Label:

Original Address https://www.douban.com/note/271270932/

The judgment of a number is n no is the prime numbers can be removed from 2 to the square root n in turn, if n can be divided into one of the n is not prime, otherwise n is a prime number. can also use the Eratosthenes sieve method, the construction of the prime number of the table, starting from 2, followed by listing the subsequent numbers, if a number is a multiple of the preceding number, then deleted from the table, that is, the deletion of the multiples of all primes, the last table is a total of prime numbers of the table. For the implementation of the program, you can set a stack, the initial stack of only one element 2, so that the cumulative from 3, and judge if I is not a multiple of any number in the stack, then I into the stack, or continue to loop until the requirements are reached.

The above two methods can be used for the judgement of the smaller number, but when the number is very large, the efficiency of both methods will be very low, so we have to find a faster way to determine whether a number is a prime. First look at several theorems:

Theorem: Set n>1 is an odd number, if there is an integer a for each element q of n-1, then n is the prime number:

a^ (n-1) ≡1 (mod n)

a^ ((n-1)/q) ≠1 (mod n)

Fermat theorem: If P is a prime number, then for any positive integer a≠0 (mod p), there is

a^ (p-1) ≡1 (mod p)

Prime Properties: a^ ((p-1)/2) ≡ (a/p) (mod p), where p is a prime number, (a/p) is an Jacobian symbol

According to the above theorem, we can get some efficient methods of primality judgement. Here are three types of:

Fermat primality test, Lehmann primality test and Solovay-strassen primality test.

The first, Fermat primality test:

Algorithm Fermat (n,t), where n>2 is odd and T is the number of tests.

1) for I from 1 to t do the following loops:

1.1) Randomly select a,1<a<n-1;

1.2) Calculate D=GCD (a,n) and return "composite" if d>1. Otherwise

1.3) Calculate R≡a ^ (n-1) (mod n);

1.4) If r≠1, return "composite".

2) return "prime number".

The algorithm mainly applies the Fermat theorem, but a^ (p-1) ≡1 (mod p) is only a necessary condition for prime numbers. The error probability of the above algorithm to judge a composite as a prime number is 1/2^t, but the decision to return composite is always correct. As long as you increase the number of tests T, you can reduce the probability of error to nearly 0.

The second type, Lehmann primality test:

1) for I from 1 to t do the following loops:

1.1) Select a random number of less than n B;

1.2) Calculate b^ ((n-1)/2) mod n;

1.3) If b^ ((n-1)/2) ≠1 or-1, then return composite; (n is definitely not a prime number)

2) returns the prime number. (n not the probability of a prime number is at most 50%)

The algorithm mainly uses the first theorem mentioned above, 2 is a prime number and is a n-1 factor, here instead of Q.

The third Kind, Solovay-strassen primality test

1) for I from 1 to t do the following loops:

1.1) Select a random number of less than n B;

1.2) Calculate j≡b^ ((n-1)/2) mod n;

1.3) If j≠1 or-1, then return n is not a prime number;

1.4) Calculate Jacobi Symbol J (b,n) = (b/n);

1.5) if J≠ (b/n), returns n is not a prime number.

2) returns n is the prime number

The 1.3 of the algorithm also uses the first theorem to determine the composite. And then use the prime character to strengthen the judgment, so this test accuracy is higher.

Three algorithms are critical one step is to calculate a number of power modulus n value, such as Fermat primality test, calculation calculation R≡a ^ (n-1) (mod n), if the use of a successive to calculate the way, time complexity is O (n), rather than the beginning of the two algorithms. Therefore, to get the efficient primality judgment algorithm, we need to optimize this step.

One drawback of successive computations is that the information that has been obtained in each cycle has not been fully exploited. Then it can be thought that, if you can record the a^2 mod n, a^4 mod n,......, as in manual calculations, choose these values for each calculation as needed, such as a^254 MoD 255. Figure out the A^2 mod 255, a^4 mod 255,......, a^128 mod 255, you can calculate a^254 mod 255=a^128*a^64*a^32*a^16*a^8*a^4*a^2 MoD 255 based on the calculated results, taking advantage of the information already available.

So a natural idea is to first loop over the value of A^i mod n in a table, where I is a power of 2, and then find out that the n-1 binary representation is stored in the array from low to High, R is initially 1, the array is traversed, and a bit is 1 when the corresponding position in the table A^i MoD The value of n multiplied by R is assigned to r, so the value of a^ (n-1) mod n is obtained after looping over and over again, and the speed is greatly increased. The original calculation a^64 need 64 times, improved only calculate a^2,a^4, a^8,a^16,a^32,a^64 mod n a total of 6 times, and after these 6 calculations, a 1~64 square modulo n can be calculated, multiple tests can be used, Even a large number of tests can be highly efficient. For long Long data, it is only possible to loop 64 times. The time complexity is reduced from O (n) to O (Logn).

This step is implemented, the other details only need a little debugging, here is only the code Solovay-strassen primality test.

#include <stdio.h>

#include <stdlib.h>

#include <time.h>

#define Max_time 11111

#define Data_typelong Long

BOOL Solovay_strassen (data_type n,int t);

int Jacobi (data_type a,data_type N);

Data_type computer (data_type a,data_type k,data_type N);//calculate R=A^K mod n

int Dectobin (data_type num,int a[]);//decimal into binary, return bits number

int main ()

{

Data_type N;

while (1)

{

printf ("Please enter the number to be judged: \ n");

scanf ("%lld", &n);

if (n<=1| | (n>2&&n%2==0) | |! Solovay_strassen (n,n>max_time? Max_time:n-2))

printf ("%lld" is not a prime number \ n);

Else

printf ("%lld is prime" \ n);

printf ("\ n");

}

return 0;

}

BOOL Solovay_strassen (data_type n,int t)

{

int i;

Data_type Rand_num,r,jac;

Srand ((unsigned int) time (NULL));

for (i=0;i<t;i++)

{

Note that this section is used to determine if there is a random number repetition, such as repetition is regenerated, and when N is large enough, this paragraph can theoretically be ignored

/*data_type choosed[max_time];//records the selected random number

BOOL flag;//tag for duplicates

Do

{

flag=0;

Do

{

Rand_num=rand ()%n;

}while (rand_num<=1| | RAND_NUM>N-1);

for (int j=0;j<i;j++)

{

if (Rand_num==choosed[j])//has been selected

{

flag=1;//Mark bit is 1

Break

}

}

}while (flag);

choosed[i]=rand_num;*/

Do

{

Rand_num=rand ()%n;

}while (rand_num<=1| | RAND_NUM>N-1);

R=computer (Rand_num, (n-1)/2,n);

if (! ( 1==r | | r==n-1))

return 0;

Jac=jacobi (Rand_num,n);

if (jac<0)

Jac=n+jac;

if (R!=jac)

return 0;

}

return 1;

}

int Jacobi (data_type a,data_type N)

{

Data_type temp,e=0,a1,n1;

int s;

if (0==a | | 1== a)

return 1;

Temp=a;

while (temp%2==0)

{

temp/=2;

e++;

}

A1=temp;

if (0== e%2)

S=1;

Else

{

if (1== n%8| |7== n%8)

S=1;

else if (3== n%8| | 5== n%8)

S=-1;

}

if (3== n%4&&3== a1%4)

S=-s;

N1=N%A1;

if (1== A1)

return s;

Else

Return S*jacobi (N1,A1);

}

int Dectobin (data_type num,int a[])//decimal converted to binary, return bits number

{

int bitnum;

for (Bitnum=0;num; bitnum++)

{

if (0==num%2)

a[bitnum]=0;

Else

A[bitnum]=1;

num/=2;

}

return bitnum;

}

Data_type computer (data_type a,data_type k,data_type N)

{

Data_type tmp;

Data_type power[8*sizeof (data_type)]={0};

int i,bitnum;

int bin[8*sizeof (data_type)]={0};

Bitnum=dectobin (K,bin);//convert n-1 to binary, binary bits assigned to Bitnum

Tmp=a;

power[0]=tmp;

for (i=1;i<bitnum;i++)

{

tmp= (tmp*tmp)%n;

power[i]=tmp;

}

for (i=0,tmp=0;i<bitnum;i++)

{

if (bin[i]==1)

{

if (0==tmp) tmp=1;

Tmp= (Tmp*power[i])%n;

}

}

return TMP;

}

Reprint primality Test