`

python 费马检测

 
阅读更多

 

费马小定理:

如果 n 是一个素数,a 是小于 n 的任意正整数,那么 a 的 n 次方与 a 模 n 同余。(两个数称为是模 n 的同余,如果它们除以 n 的余数相同。数 a 除以 n 的余数称为 a 取模 n 的余数,或简称为 a 取模 n)。

如果 n 不是素数,那么,一般而言,大部分的 a < n 都将满足上面的关系。这就引出了下面这个检查素数的算法:

对于给定的整数 n,随机任取一个 a < n 并计算出 an 取模 n 的余数。如果得到的结果不等于 a,那么 n 就肯定不是素数。如果它就是 a,那么 n 是素数的机会就很大。现在再另取一个随机的 a 并采用同样的方式检查。如果它满足上述等式,那么我们就能对 n 是素数有更大的信心了。通过检查越来越多的 a 值,我们就可以不断增加对有关结果的信心。这一算法称为费马检查。

读起来理解不直观?那么我这么总结下吧。

假如a是一个整数,p是一个素数,那么 ap = a (mod p)

如果a不是p的倍数,这个定理也可以写成 ap-1 = 1 (mod p)

举个例子,67是一个素数,则266 mod 67 = 1。

 

import random

def expmod(base,exp,m):
	if exp==0:
		return 1
	elif exp%2==0:
		return expmod(base,exp/2,m)**2 % m
	else:
		return expmod(base,exp-1,m)*base % m
def fermat_test(n):
	a=random.randint(1,n-1)
	if a==expmod(a,n,n):
		return 1
	else:
		return 0
def fermat_prime(n,time):
	if time==0:
		return 1
	elif fermat_test(n)==1:
		return fermat_prime(n,time-1)
	else:
		return 0
#print fermat_test(11)
print fermat_prime(99,100)

 对于为啥不直接用 a^exp 来求幂值 解释如下:

【转】http://www.blogjava.net/killme2008/archive/2007/05/11/116813.html

直接定义(expmod base exp m)为base^exp基于m的模(modulo)

(define (expmod base exp m)

  (remainder (fast-expt base exp) m))

在理想情况下是正确的,在语义上与原定义是等价的,甚至递归层数

都是一样的,而且更加直观。

 

但在实践中,这样的定义是不可行的,这也是为什么我们要采用原文中的定义

的原因:因为base^exp很可能是一个非常大的数。比如,当我们取第二个

测试例子中的n=1000000时,base是[1,999999]区间中的任意

随机数,它的平均取值为50000,而exp=1000000。50000^1000000是一个大得

惊人的数,无论是fast-expt的层层函数调用计算,还是用remainder对其取模,

计算量都是很大的。

 

而相反,原始的expmod函数

(define (expmod base exp m)

  (cond ((= exp 0) 1)

        ((even? exp)

         (remainder (square (expmod base (/ exp 2) m))

                    m))

        (else

         (remainder (* base (expmod base (- exp 1) m))

                    m))))

通过分解(a*b mod n) 为 ((a mod n) * (b mod n) mod n),使得每层递归

调用的计算参数和返回值总是小于n (x mod n < n),即便是计算过程中出现

的最大数(a mod n) * (b mod n) 也依然是要小于n^2, 相对于前者n^n的数

量级,实在是小得多,这样就避免了大数的计算问题。

 

比如经测试,在使用新的expmod的情况下,1009的验证需要1.2ms的时间,

1000003的验证需要 93680ms,远高于原来的expmod函数。

 

这也同时印证了我们在1.24题中的分析,同样的操作在不同字长的数字上的

代价是不同的。1000000的验证时间现在是1000的8000多倍,远不再是2倍左右

的关系。在1.24中的,因为expmod算法的控制,操作数最多是n^2级的,字长

所引起的差距并不明显,只在10^6-10^12间产生了一点点阶跃;而这里的算法

中, 操作数可以达到n^n级,当n=1000时,1000^1000的字长大约在10000位(二

进制数)左右,而n=1000000时1000000^1000000的字长则达到在20000000位(二

进制数)左右,这字长的巨大差距导致了我们在1.24中已经发现的问题更加明显。

 

分享到:
评论

相关推荐

    Python素数检测的方法

    本文实例讲述了Python素数检测的方法。分享给大家供大家参考。具体如下: 因子检测: 检测因子,时间复杂度O(n^(1/2)) def is_prime(n): if n &lt; 2: return False for i in xrange(2, int(n**0.5+1)): if n%i...

    素数检测算法

    费马检测法的实现代码可以表示为Python中的函数。例如: ```python def prime_test_fermat(n): if n == 1: return False for a in range(2, 1+int(floor(sqrt(n)))): if pow(a, n-1, n) != 1: return False ...

    Python 实现多种素数判断算法

    内容概要:本文详细介绍了四种常见的素数判断算法——试除法、埃拉托斯特尼筛法、米勒-拉宾素性检验以及费马素性检验的基本原理及其 Python 实现方法。此外,还简要提到了其他两种算法:威尔逊定理和阿格拉瓦尔-卡亚...

    RSA.rar_in_rsa_rsa algorithm_rsa python

    6. fermat_primality_test.py:费马小定理素数测试,也是用于检测素数,它是米勒-拉宾测试的一个简化版本。 7. euclid_algo.py:欧几里得算法,用于计算两个整数的最大公约数。 这些Python脚本共同构建了一个完整...

    AKS prime 素数检测算法

    这是基于费马小定理的一个扩展,对于素数n,这个条件应该总是成立的。 5. **多项式分解**:如果在第4步找到了这样的a,进一步检查多项式(x-a)^n - (x-a)是否可被(x^r - x)整除。如果可以,那么n是素数;如果不能,...

    MathematicalPlayground:Python脚本演示数学概念

    此外,项目可能还包含关于数论的脚本,比如素数检测、费马小定理等,这些都是密码学和计算机科学中的关键概念。还有可能涉及图论,Python可以轻松地表示和操作图,这对于理解和解决网络问题非常有用。 对于更高级的...

    python输出第n个默尼森数的实现示例

    默尼森数是由法国数学家皮埃尔·德·费马以他的朋友、神父莫尼森的名字命名的。一个默尼森数是形式为\( M = 2^p - 1 \)的素数,其中\( p \)本身也是一个素数。如果这样的条件成立,那么\( M \)就是一个默尼森数。...

    primality_test:Miller检验-Miller–Rabin素数检验的未经证实的确定性版本

    这是素数检验的一个基础,因为它提供了一种检测一个数是否可能为素数的方法。 **Miller-Rabin检验**的工作原理如下: 1. **分解质因数**: 首先,将给定的数`n`表示为`2^r * d + 1`,其中`d`是奇数且`n-1`能被2整除...

    4-prime-generation.rar_generation

    "4-prime-generation.rar_...总的来说,这个项目涉及了素数理论、素数检测算法(费马特检验)、文件操作、程序设计以及文件压缩等多方面的IT知识。通过这样的实践,可以加深对这些概念的理解,并锻炼编程技能。

    pyANT:一小包包含高级数论课程的算法

    通过使用pyANT,用户可以轻松处理模运算、同余类、素数检测、欧几里得算法、扩展欧几里得算法、费马小定理、中国剩余定理等基础和高级数论问题。 1. **模运算与同余类**:pyANT提供了一系列的函数来处理模运算,...

    算法-判决素数个数(信息学奥赛一本通-T1409)(包含源程序).rar

    描述中的“包含源程序”意味着这个压缩包可能包含至少一个编程文件,可能是C++, Python, Java或其他编程语言,展示了如何实现判断一个数是否为素数的算法。这些源代码对于学习者来说是非常宝贵的资源,可以用来理解...

    number-theory

    素数检测算法,如埃拉托斯特尼筛法,是数论的基础。 2. **最大公约数(GCD)与最小公倍数(LCM)**:欧几里得算法可以有效地找到两个数的最大公约数,而最小公倍数可以通过两数乘积除以GCD来求得。 3. **模运算与...

    算法-刻录光盘(信息学奥赛一本通-T1383)(包含源程序).rar

    7. **数学应用**:组合数学、概率论、数论、图论等数学知识在算法设计中经常被用到,如鸽巢原理、费马小定理、欧拉函数等。 8. **编程语言基础**:C++、Python等编程语言的基本语法、输入输出、文件操作等,是实现...

    Prime-or-not:由Harshith Ramesh开发

    2. **算法实现**:如何用编程语言(可能是Python、Java或其他语言)实现素数检测算法。这通常涉及到循环、条件语句和数学逻辑。 3. **效率优化**:对于大整数,快速素数检测算法的实现,如米勒-拉宾测试。该算法...

    对称素数演算程序

    4. **素数检测算法**:程序可能包含一种或多种用于检查一个数是否为素数的算法,如埃拉托斯特尼筛法、费马小定理、米勒-拉宾素性检验等。这些算法在计算对称素数时起到关键作用。 5. **编程语言**:这个程序可能是...

Global site tag (gtag.js) - Google Analytics