簡體   English   中英

生成具有指定最后數字的大質數

[英]Generate large prime number with specified last digits

想知道如何生成512位(155位十進制數)素數,其中五位十進制數被指定/固定(例如。*** 28071)?

在沒有任何規范的情況下生成簡單素數的原則是可以理解的,但我的情況更進一步。

至少,我應該從哪里開始提示?

Java或C#是首選。

謝謝!

我想唯一的辦法就是首先生成一個150個十進制數字的隨機數,然后通過number = randomnumber * 100000 + 28071將28071追加到它后面,然后用類似的東西強行推出它

while (!IsPrime(number))
    number += 100000;

當然這可能需要一段時間來計算;-)

您是否嘗試生成此類數字並進行檢查? 我希望這個速度可以接受。 素數密度僅作為數字的對數減小,所以我希望你嘗試幾百個數字,直到你達到一個素數。 ln(2^512) = 354所以350中的一個數字將是素數。

粗略地說,素數定理指出如果選擇一些大數N附近的隨機數,則它的素數的概率約為1 / ln(N),其中ln(N)表示N的自然對數。例如在N = 10,000附近,大約九分之一的數字是素數,而在N = 1,000,000,000附近,每21個數字中只有一個是素數。 換句話說,N附近素數之間的平均差距大約是ln(N)

(來自http://en.wikipedia.org/wiki/Prime_number_theorem

您只需要注意最終數字的數字。 但我認為這就像檢查最后一個數字不能被2或5整除一樣容易(即它是1,3,7或9)。

根據這個性能數據,你可以對每秒512位數據進行2000次ModPow操作,並且由於簡單的質數測試是檢查2^(p-1) mod p=1這是一個ModPow操作,你應該能夠每秒使用您的屬性生成多個素數。

所以你可以做(​​偽代碼):

BigInteger FindPrimeCandidate(int lastDigits)
{
    BigInteger i=Random512BitInt;
    int remainder = i % 100000;
    int increment = lastDigits-remainder;
    i += increment;
    BigInteger test = BigInteger.ModPow(2, i - 1, i);
    if(test == 1)
      return i;
    else
      return null;
}

並對該函數的結果進行更廣泛的質檢。

正如@Doggot所說,但從最少可能的150位數字開始,以28071結尾,意味着100000 .... 0028071,現在每次加100000並且測試主要使用米勒rabin,就像我在這里提供的代碼一樣,它需要一些定制。 如果返回值為true,請首先檢查它是否准確。

您可以使用僅包含滿足您特殊條件的數字的篩子來篩選出可被小素數整除的數字。

對於每個小素數p您需要找到正確的起點和步驟,考慮到篩子中只有每個第100000個數字。

對於在篩子中存活的數字,您可以使用BigInteger.isProbablePrime()來檢查它是否具有足夠概率的素數。

設ABCDE為十進制的五位數,您正在考慮這個數字。 根據Dirichlet關於算術進展的定理 ,如果ABCDE和100000是互質的,那么形式為100000 * k + ABCDE的無限多個素數。 既然您正在尋找素數,那么無論是2還是5都不會划分ABCDE,因此ABCDE和100000是互質的。 因此,有你正在考慮形式的無限多的素數。

您可以通過添加額外約束來擴展用於生成大質數標准方法之一,即最后5位十進制數字必須正確。 天真的,您可以將其添加為額外的測試,但它會增加找到合適的素數的時間10 ^ 5。

不那么天真:生成一個隨機的512位數,然后設置足夠的低位,以便十進制表示以所需的順序結束。 然后繼續正常的素性測試。

讓我們考慮蠻力。 看看這個非常有趣的文章“素數彩票”:

鑒於最后一個表中的最后一個條目,有大約2.79 * 10 ^ 14個素數小於10 ^ 16。 因此,大約每35個數字是該范圍內的素數。

編輯:查看CodeInChaos的評論 - 如果你只走幾千個512位數字,最后5位數字固定,你會很快找到一個。

http://www.merriampark.com/bigsqrt.htmBigSquareRoot類的幫助下,我將蠻力算法從int世界重寫為BigDecimal算法。 (注意,從1到1000,據說恰好是168個素數。)

對不起,但如果你把你的范圍放在那里,即<10 154 ; 10 155 -1>,你可以讓你的電腦工作,當你退休時,你可能會得到結果......它太慢了!

但是,您可以通過某種方式找到此部分中至少有一部分與此線程中的其他答案結合使用。


package edu.eli.test.primes;

import java.math.BigDecimal;

public class PrimeNumbersGenerator {

  public static void main(String[] args) {
//    BigDecimal lowerLimit = BigDecimal.valueOf(10).pow(154); /* 155 digits */
//    BigDecimal upperLimit = BigDecimal.valueOf(10).pow(155).subtract(BigDecimal.ONE);

    BigDecimal lowerLimit = BigDecimal.ONE;
    BigDecimal upperLimit = new BigDecimal("1000");

    BigDecimal prime = lowerLimit;
    int i = 1;

    /* http://www.merriampark.com/bigsqrt.htm */
    BigSquareRoot bsr = new BigSquareRoot();
    upperLimit = upperLimit.add(BigDecimal.ONE);
    while (prime.compareTo(upperLimit) == -1) {

      bsr.setScale(0);
      BigDecimal roundedSqrt = bsr.get(prime);

      boolean isPrimeNumber = false;
      BigDecimal upper = roundedSqrt;
      while (upper.compareTo(BigDecimal.ONE) == 1) {

        BigDecimal div = prime.remainder(upper);
        if ((prime.compareTo(upper) != 0) && (div.compareTo(BigDecimal.ZERO) == 0)) {
          isPrimeNumber = false;
          break;
        } else if (!isPrimeNumber) {
          isPrimeNumber = true;
        }

        upper = upper.subtract(BigDecimal.ONE);
      }

      if (isPrimeNumber) {
        System.out.println("\n" + i + " -> " + prime + " is a prime!");
        i++;
      } else {
        System.out.print(".");
      }
      prime = prime.add(BigDecimal.ONE);
    }
  }

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM