C++ 100%确定的快速素性测试?

C++ 100%确定的快速素性测试?,c++,algorithm,math,primes,gmp,C++,Algorithm,Math,Primes,Gmp,我对任意大小的数据类型使用GMP(带MPIR)。我还使用了它的素性测试函数,它使用Miller-Rabin方法,但它不精确。这就是我想要解决的问题 通过使用蛮力和sqrt方法,我能够确认数字18446744073709551253是素数 是否有任何方法可以100%准确地检查大数是否为素数 它不应该使用太多的内存/存储空间,几兆字节是可以接受的 它应该比我使用的sqrt方法更快 它应该适用于大小至少为64位或更大的数字 最后,它应该是100%准确,没有可能 我有什么选择 虽然我可以接受蛮力法(

我对任意大小的数据类型使用GMP(带MPIR)。我还使用了它的素性测试函数,它使用Miller-Rabin方法,但它不精确。这就是我想要解决的问题

通过使用蛮力和sqrt方法,我能够确认数字18446744073709551253是素数

是否有任何方法可以100%准确地检查大数是否为素数

  • 它不应该使用太多的内存/存储空间,几兆字节是可以接受的

  • 它应该比我使用的sqrt方法更快

  • 它应该适用于大小至少为64位或更大的数字

  • 最后,它应该是100%准确,没有可能

我有什么选择


虽然我可以接受蛮力法(64位数字),但出于兴趣,我希望更快更大。此外,64位数字检查太慢:总共43秒

对于非常大的数字,是一个确定性素性测试,在时间O(log7.5n log n)中运行,其中n是感兴趣的数字。这是指数速度比O(√n) 算法。然而,该算法具有较大的常数因子,因此在您的数字变大之前,它是不实用的


希望这有帮助

一般来说,物理计算机上不可能100%确定,因为某些组件发生不可见故障的可能性很小,但有限,最后给出的答案不正确。考虑到这一事实,您可以运行足够多的概率Miller-Rabin测试,使数字合成的概率远远小于硬件失败的概率。测试高达1/2^256的确定度并不困难:

boolean isPrime(num)
  limit <- 256
  certainty <- 0
  while (certainty < limit)
    if (millerRabin returns notPrime)
      return false
      exit
    else
      certainty <- certainty + 2
    endif
  endwhile
  return true
end isPrime
boolean isPrime(num)
对于小n,试验分部工程的限制;那里的极限可能在10^12左右。对于稍大的n,有各种研究(见Gerhard Jaeschke和Zhou Zhang的著作)计算各种Miller-Rabin基集合的最小伪素;这将带您到大约10^25。在那之后,事情变得困难起来

素性证明的“大炮”是APRCL方法(可以称为雅可比和或高斯和)和ECPP方法(基于椭圆曲线)。两者都很复杂,所以您需要找到一个实现,而不是编写自己的实现。这些方法都可以处理几百位数的数字

AKS方法经证明是多项式时间的,易于实现,但比例常数非常高,因此在实践中没有用处

如果你能将n-1因子化,甚至部分因子化,波克林顿的方法可以确定n的素性。Pocklington的方法本身很快,但因子分解可能不是

对于所有这些,在你试图证明一个数之前,你需要合理地确定它是素数。如果你的数字不是素数,所有这些方法都会正确地确定它,但首先他们会浪费很多时间来证明一个复合数字是素数


我在我的博客上有和的实现。

证明方法取决于你试图证明的素数类型(例如,梅森素数有证明素数的特殊方法,仅适用于它们)和十进制数字的大小。如果你看的是数百位数字,那么只有一个解决方案,尽管这是一个不足的解决方案:AKS算法。可以证明,对于足够大的素数,它比其他素数证明算法要快,但当它变得有用时,它将花费很长时间,因此不值得费心

大数的素性证明仍然是一个尚未充分解决的问题。如果是的话,EFF奖将全部颁发,密码学将出现一些问题,不是因为素数列表,而是因为用于查找素数的方法


我相信,在不久的将来,一种证明素数的新算法将出现,它不依赖于一个预生成的素数列表,直到n的平方根,也不需要使用蛮力方法来确保平方根下的所有素数(以及许多非素数)都被用作n的素数的见证。这个新算法可能依赖于比解析数论所使用的数学概念简单得多的数学概念。素数是有规律的,这是肯定的。识别这些模式完全是另一回事。

对于小于等于2^64的数字,Baillie-Pomerance-Selfridge-Wagstaff测试是可靠的。以上是APRCL或椭圆曲线素性证明。@Grizzly,我在哪里需要它?当然,在我的脑海中:)如果我在一个程序中做了一个按钮,用来判断这个数字是否是素数,听到“可能是素数,我不知道,问问别人吧!”的声音会让人很恼火:p@Rookie:“也许”这个词不太合适。使用Miller-Rabin,您可以轻松地使误报概率小于计算机错误计算(内存中的位错误毕竟并非不可能)或随机起火的概率。因为我假设你没有考虑这些情况,100%的确定性是一个不确定的术语。@Grizzly,我知道有可能出错,这让我很恼火,通常在可能的情况下,幸运的是,我设法键入了落入错误坑的唯一可能值!(我不是在开玩笑!)。此外,我希望这类事情是准确的。正如你所说的“也许”一词,如果“素数”不是100%确定为素数,我会说这里的术语“素数”不是正确的。@菜鸟:那么你怎么处理随机位错误、自发硬件故障等的可能性呢?我的观点是,假设1/2^512的概率不太可能。这种可能性根本不值得担心,因为a)由于硬件缺陷,计算失败的可能性要比由于误报而失败的可能性大得多,b)你不会