有效地生成一个范围内的随机质数

时间:2019-04-25 22:21:36

标签: java performance primes

我只需要获得[2,n ^ 2]范围内的一个随机素数,其中n可以非常大(10 ^ 9到10 ^ 32)。我知道那些作业问题,例如“如何在给定范围内打印质数”,“依拉藤森的筛子”等。

如果可能的话,我想避免计算所有素数并随机选择一个。

我也不确定是否从范围中选择一个随机数并检查素数是否是解决此问题的一种优雅/有效的方法。

这与安全性无关。它只是算法实现(尝试实现)的一部分,它检查两个非常大的文件(> 1TB)是否相同。

有什么想法可以得到一个专注于性能的绝对质数的随机数吗?

编辑 我正在尝试做的一个非常幼稚和简化的实现:

import java.math.BigInteger;
import java.util.stream.Collectors;

public class NewClass1 {    

    public static void main(String[] args) {
        //imagine this is my content of first file which is not at the same place as file two
        String file1 = "RDNZL";        
        //convert the content to bits
        file1 = toBits(file1); // 0101001001000100010011100101101001001100  

        //convert bits to number
        BigInteger  x = new BigInteger (file1, 2); //353333303884

        long p = 1187;  // select a random number between 2 and 1600 (String length * 8 bits = 40)
        // send p and x % p to validiate,
        long xMp = x.mod(BigInteger.valueOf(p)).longValue(); 
        System.out.println(check(p, xMp));
    }
    public static String toBits(String file){
        //convert each char to 8 bits and concat to string
        //just for simplification, i'am going to find a better way to solve this
        return file.chars().boxed()
                .map(Integer::toBinaryString).map(e->String.format("%8s", e).replace(' ', '0'))
                .collect(Collectors.joining("")); 
    }
    public static boolean check(long p, long xMp){
        //the other file which is somewhere else, in the cloud etc. 
        String file2 = "RDNZL";        
        file2 = toBits(file2); 

        BigInteger  y = new BigInteger (file2, 2); 
        long yMp = y.mod(BigInteger.valueOf(p)).longValue();
        return yMp == xMp;
    }
}

如果yMp!= xMp且置信度为100%的文件不同,则算法无法识别出它们是否不同的可能性很小。

2 个答案:

答案 0 :(得分:3)

使用BigInteger及其nextProbablePrime()方法。

public static BigInteger randomPrime(int numBits) {
  BigInteger max = BigInteger.ONE.shiftLeft(numBits);
  BigInteger prime;
  do {
    BigInteger integer = new BigInteger(numBits, ThreadLocalRandom.current()); // Pick a random number between 0 and 2 ^ numbits - 1
    prime = integer.nextProbablePrime(); // Pick the next prime. Caution, it can exceed n^numbits, hence the loop
  } while(prime.compareTo(max) > 0);
  return prime;
}

一种替代方法是使用BigInteger​(int bitLength, int certainty, Random rnd)构造函数,但是它将找到恰好具有bitLength位的数字,这很不方便,因为它不会低于n ^(bitLength-1)。 / p>

答案 1 :(得分:0)

在x处找到素数的概率为1 / ln(x)。您的情况是n²,n = 10 ^ 32。因此,可能性为ln(10 ^ 64)或大约1/150。这意味着您必须平均测试大约150个数字,直到找到质数为止。

我没有Java,但是我可以根据PSW primality test从Python给您结果。积分会从@primo转移到Codegolf,尤其是this answer

start = time()
n = next_prime((10**32)**2)
end = time()
print (n, " calcualted in ", end-start)

10000000000000000000000000000000000000000000000000000000000000057 calcualted in  0.00302 sec

是的,有可能同时以一种有效的方式。

结果由Wolfram Alpha确认。