In a limited time, calculate a prime number as large as possible
1. Problem
- Limited time: within an acceptable time range, do not rely on brute force solution
- As large as possible: the upper limit of the prime can be calculated
- Prime number: The factor is only 1 and its own natural number
2. Generation of prime numbers
The steps to generate a large prime number with n decimal digits are as follows:
- Generate an n-bit random number p
- If the lowest bit is an even number, add 1 to ensure that the prime number is an odd number, thus ensuring an average saving of half of the computing time
- Check to make sure that p is not divisible by any small factors, such as
3, 5, 7, 11
and the like, the purpose is to exclude the possibility of most of the number p is laminated, the steps for reducing the total number of primes p be tested, thus saving computation time. I used all prime numbers less than 20 except 2 (because I have checked the parity of p) to test p for their divisibility - Generating a random number, to carry out a
Rabin- Miller
test, to pass the test if p is a further generates a random number, and test again select a smaller value, in order to ensure a faster operating speed, for threeRabin-Miller
tests (1 It seems to be enough, but to ensure higher accuracy, you can do it a few times) - If p passes the test, then p is a prime number, otherwise add 2 to the original tested number to get a new number, and then test the new number until a prime number is found
3. Miller-Rabin algorithm
Miller-Rabin
The algorithm is a probabilistic primality test algorithm, so the difference between this algorithm and the general fact-based primality test method is: there is a certain rate of misjudgment. However, in the case of multiple tests for a large number to be tested, the false positive rate can be controlled within a negligible range. Miller-Rabin
Algorithm based on Fermat
the algorithm, the latter modification, improvement.
First introduced Fermat
Theorem: n is an odd prime, a is any integer (1 ≤ a ≤ n-1)
, then a^(n-1)≡1(mod n)
according to the theorem can know, for a given test number n, by setting primality test algorithm calculation w = a^(n-1)%n
to determine the results.
-
W!=1
, N must not be a prime number; -
W==1
, N may be a prime number;
Second detection reintroduction theorem, if n is an integer, and 0<x<n
, then: x2%p=1
are: x= 1 / x = p-1
. If n is a prime number, it ( n-1 )
must be an even number, so it can be made (n-1)=m*(2^q)
that m is a positive odd number (if n is an even number, then the above m*(2^q)
must be decomposed into a positive odd number times 2 to the power of k), q is a non-negative integer.
With Fermat
theorem, the following a^(m)%n、a^(2m)%n、a^(4m)%n、a^(m*(2^q))%n
tests: . The process of conducting these tests is: Miller-Rabin
testing.
Misjudgment rate: If n is a prime number and a is a positive integer less than n, then n is a Miller test based on a and the result is true. The Miller test is performed k times, and the error probability of treating composite numbers as prime numbers will not exceed 4 ^ (-k) at most.
Four. Java program implementation
/**
* 题目8:计算一个尽可能大的素数
* 题目描述:在有限的时间内,计算出一个尽可能大的素数。
*/
package edu.sust;
import java.util.Random;
import java.util.Scanner;
public class PrimeNumber {
public static void main(String[] args) {
long startTime = System.currentTimeMillis(); //开始时间
Scanner scanner = new Scanner(System.in);
long executeTime;//程序执行时间
System.out.println("请输入程序运行的时间(毫秒为单位):");
executeTime = scanner.nextLong();
long endTime = System.currentTimeMillis(); //结束时间
int maxPrime = 2; //最大素数
while (endTime - startTime < executeTime) {
int num = getRandom();
if (num > maxPrime) {
if (MillerRabin(num, 3))
maxPrime = num;
}
endTime = System.currentTimeMillis();
}
System.out.println(maxPrime);
scanner.close();
}
public static int getRandom() {
Random random = new Random();
int num = random.nextInt(Integer.MAX_VALUE);
if ((num & 1) != 1) {
num++;//若最低位为偶数, 则将它加1, 以确保该素数为奇数
}
//检查以确保 p 不能被任何小素数整除
int[] primes = {3, 5, 7, 11, 13, 17, 19};
for (int i = 0; i < primes.length; i++) {
if (num % primes[i] == 0)
return -1;
}
return num;
}
/**
* 利用费马小定理求大数幂取模
*
* @param a 底数
* @param b 指数
* @param n 模数
* @return 返回(a ^ b) mod n的值
*/
public static int FermatPower(int a, int b, int n) {
int result = 1;
while (b > 0) {
if ((b & 1) == 1)
result = (result * a) % n;
if ((a * a) % n == 1 && a != 1 && a != n - 1)
return -1;// 二次探测
b >>= 1;
a = (a * a) % n;
}
return result;
}
/**
* Miller-Rabin素性测试
*
* @param n 待测随机数
* @param time 检测次数
* @return 若通过测试,返回true,否则返回false
*/
public static boolean MillerRabin(int n, int time) {
Random random = new Random();
for (int i = 0; i < time; i++) {
if (FermatPower(random.nextInt(n - 1) + 2, n - 1, n) != 1)
return false;
}
return true;
}
}
references
- Liu Shaotao, Ling Jie. Data encryption algorithm and generation and operation of large prime numbers [J]. Journal of Guangdong University of Technology, 2001 (04): 27-31.
- Zhang Hong, Liu Xiaoxia, Zhang Ruoyan. Generation of secure large prime numbers in RSA public key cryptosystem [J]. Computer Technology and Development, 2008 (09): 137-139 + 143.
- Han Lie, Fu Xinghua, Liu Xinhua, et al. A method for generating large prime numbers based on RSA public key cryptosystem [J]. Journal of Guizhou University (Natural Science), 2005 (04): 101-104.