【问题标题】:Generate large prime number with specified last digits生成具有指定最后一位的大素数
【发布时间】:2011-05-20 06:47:06
【问题描述】:

想知道如何生成 512 位(155 个十进制数字)质数,其中最后五个十进制数字是指定/固定的(例如 ***28071)??

生成没有任何规范的简单素数的原理是可以理解的,但我的情况更进一步。

任何提示,至少,我应该从哪里开始?

Java 或 C# 更可取。

谢谢!

【问题讨论】:

  • 如果不通过 155 位素数并检查每个素数,这听起来很困难,如果不是不可能的话。有趣的问题:P
  • 另外,这个问题可能更适合math.stackexchange.com
  • 不要暴力破解素数,暴力破解满足标准的数字并检查它们的素数。这不应该那么慢,因为素数密度相当高。
  • @thejh:你不能筛到 10^155。
  • 感谢大家的贡献!问题暂时解决了。

标签: c# java algorithm primes


【解决方案1】:

我想唯一的方法是首先生成一个 150 位十进制数字的随机数,然后通过执行 number = randomnumber * 100000 + 28071 在其后面附加 28071,然后使用类似

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

当然这可能需要一段时间来计算 ;-)

【讨论】:

  • 不会那么慢,因为你只需要尝试几百次。
  • @CodeInChaos 并不是只需要检查几次,而是 IsPrime 对这么大的数字进行检查需要很长时间。
  • 如果 IsPrime 准确检查素数会很慢。阶段测试更好。
  • 我估计普通情况(非素数)的时间低于 100 毫秒,如果测试成功,您可以进行缓慢但彻底的测试。
  • 嗯,我就是这么做的。使用 isProbablePrime 蛮力强制数字 = 随机数 * 100000 + 28071。速度相当快。
【解决方案2】:

您是否尝试过仅生成这些数字并检查它们?我希望这是可以接受的快。素数密度只随着数字的对数减少,所以我希望你尝试几百个数字,直到你遇到一个素数。 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)一样简单。

根据this performance data,您每秒可以对 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;
}

并对该函数的结果进行更广泛的质数检查。

【讨论】:

    【解决方案3】:

    您可以通过添加额外的约束来扩展 standard methods for generating large primes 之一,即最后 5 位十进制数字必须正确。天真地,您可以将其添加为额外的测试,但这会使找到合适素数的时间增加 10^5。

    不那么天真:生成一个随机的 512 位数字,然后设置足够的低位,以便十进制表示以所需的序列结束。然后继续进行正常的素性测试。

    【讨论】:

      【解决方案4】:

      让我们考虑蛮力。看看这个非常有趣的文字,叫做“质数彩票”:

      鉴于最后一个表中的最后一个条目,有 ~2.79*10^14 个质数小于 10^16。因此,大约每 35 个数字都是该范围内的质数。

      编辑:查看 CodeInChaos 的评论 - 如果您只是走几千个 512 位数字并固定最后 5 位数字,您会很快找到一个。

      【讨论】:

      • 您只能尝试具有正确结束数字的数字。对于 512 位数字,每 350 个而不是第 35 个数字是素数。
      • 是的,感谢您的更正和 512 位信息,我会编辑!
      【解决方案5】:

      正如@Doggot 所说,但从以 28071 结尾的最少可能的 150 位数字开始,表示 100000....0028071,现在每次将其加起来 100000,并且主要使用 miller rabin 进行测试,就像我提供的代码 @ 987654321@,它需要一些定制。如果返回值为真,则主要检查是否准确。

      【讨论】:

        【解决方案6】:

        您可以使用只包含满足您的特殊条件的数字的筛子来过滤掉可被小素数整除的数字。

        对于每个小的素数p,您需要找到正确的起点和步骤,并考虑到筛子中只有第 100000 个数字。

        对于那些在筛子中幸存下来的数字,您可以使用BigInteger.isProbablePrime() 来检查它是否是具有足够概率的素数。

        【讨论】:

          【解决方案7】:

          http://www.merriampark.com/bigsqrt.htmBigSquareRoot 类的帮助下,我将int 世界中的蛮力算法重写为BigDecimal。 (请注意,从 1 到 1000,据说正好有 168 个素数。)

          对不起,如果你把你的范围放在那里,即 154; 10155-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); } } }

          【讨论】:

            【解决方案8】:

            让 ABCDE 是您正在考虑的以十为底的五位数字。基于Dirichlet's theorem on arithmetic progressions,如果 ABCDE 和 100000 互质,那么 100000*k+ABCDE 形式的质数有无穷多个。由于您正在寻找素数,因此无论如何 2 和 5 都不会除 ABCDE,因此 ABCDE 和 100000 是互质的。因此,您正在考虑的形式有无限许多素数。

            【讨论】:

            • 是的,但是导致素数的第一个k 可能是任意大的。多大?取决于 ABCDE。因此,您需要对k 进行暴力搜索,并对每个候选人k 进行通常昂贵的素性测试。
            猜你喜欢
            • 2013-04-02
            • 1970-01-01
            • 2018-03-12
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-11-29
            • 2012-03-18
            • 2021-12-01
            相关资源
            最近更新 更多