Python素数检测的方法


Posted in Python onMay 11, 2015

本文实例讲述了Python素数检测的方法。分享给大家供大家参考。具体如下:

因子检测:

检测因子,时间复杂度O(n^(1/2))

def is_prime(n):
  if n < 2:
    return False
  for i in xrange(2, int(n**0.5+1)):
    if n%i == 0:
      return False
  return True

费马小定理:

如果n是一个素数,a是小于n的任意正整数,那么a的n次方与a模n同余

实现方法:

选择一个底数(例如2),对于大整数p,如果2^(p-1)与1不是模p同余数,则p一定不是素数;否则,则p很可能是一个素数
2**(n-1)%n 不是一个容易计算的数字

模运算规则:

(a^b) % p = ((a % p)^b) % p
(a * b) % p = (a % p * b % p) % p

计算X^N(% P)

可以
如果N是偶数,那么X^N =(X*X)^[N/2];
如果N是奇数,那么X^N = X*X^(N-1) = X *(X*X)^[N/2];

def xn_mod_p(x, n, p):
  if n == 0:
    return 1
  res = xn_mod_p((x*x)%p, n>>1, p)
  if n&1 != 0:
    res = (res*x)%p
  return res

也可以归纳为下面的算法 两个函数是一样的

def xn_mod_p2(x, n, p):
  res = 1
  n_bin = bin(n)[2:]
  for i in range(0, len(n_bin)):
    res = res**2 % p
    if n_bin[i] == '1':
      res = res * x % p
  return res

有了模幂运算快速处理就可以实现费马检测

费马测试当给出否定结论时,是准确的,但是肯定结论有可能是错误的,对于大整数的效率很高,并且误判率随着整数的增大而降低

def fermat_test_prime(n):
  if n == 1:
    return False
  if n == 2:
    return True
  res = xn_mod_p(2, n-1, n)
  return res == 1

MILLER-RABIN检测

Miller-Rabin检测是目前应用比较广泛的一种

二次探测定理:如果p是一个素数,且0<x<p,则方程x^2%p=1的解为:x=1或x=p-1
费马小定理:a^(p-1) ≡ 1(mod p)

这就是Miller-Rabin素性测试的方法。不断地提取指数n-1中的因子2,把n-1表示成d*2^r(其中d是一个奇数)。那么我们需要计算的东西就变成了a的d*2^r次方除以n的余数。于是,a^(d * 2^(r-1))要么等于1,要么等于n-1。如果a^(d * 2^(r-1))等于1,定理继续适用于a^(d * 2^(r-2)),这样不断开方开下去,直到对于某个i满足a^(d * 2^i) mod n = n-1或者最后指数中的2用完了得到的a^d mod n=1或n-1。这样,Fermat小定理加强为如下形式:

尽可能提取因子2,把n-1表示成d*2^r,如果n是一个素数,那么或者a^d mod n=1,或者存在某个i使得a^(d*2^i) mod n=n-1 ( 0<=i<r ) (注意i可以等于0,这就把a^d mod n=n-1的情况统一到后面去了)

定理:若n是素数,a是小于n的正整数,则n对以a为基的Miller测试,结果为真.
Miller测试进行k次,将合数当成素数处理的错误概率最多不会超过4^(-k)

def miller_rabin_witness(a, p):
  if p == 1:
    return False
  if p == 2:
    return True
  #p-1 = u*2^t 求解 u, t
  n = p - 1
  t = int(math.floor(math.log(n, 2)))
  u = 1
  while t > 0:
    u = n / 2**t
    if n % 2**t == 0 and u % 2 == 1:
      break
    t = t - 1
  b1 = b2 = xn_mod_p2(a, u, p)
  for i in range(1, t + 1):
    b2 = b1**2 % p
    if b2 == 1 and b1 != 1 and b1 != (p - 1):
      return False
    b1 = b2
  if b1 != 1:
    return False
  return True
def prime_test_miller_rabin(p, k):
  while k > 0:
    a = randint(1, p - 1)
    if not miller_rabin_witness(a, p):
      return False
    k = k - 1
  return True

希望本文所述对大家的Python程序设计有所帮助。

Python 相关文章推荐
Python求两个list的差集、交集与并集的方法
Nov 01 Python
Linux下python与C++使用dlib实现人脸检测
Jun 29 Python
tensorflow实现加载mnist数据集
Sep 08 Python
Python3中lambda表达式与函数式编程讲解
Jan 14 Python
Python 中Django验证码功能的实现代码
Jun 20 Python
python Pandas库基础分析之时间序列的处理详解
Jul 13 Python
Python for循环及基础用法详解
Nov 08 Python
python函数不定长参数使用方法解析
Dec 14 Python
解决Python列表字符不区分大小写的问题
Dec 19 Python
Python为何不支持switch语句原理详解
Oct 21 Python
OpenCV利用python来实现图像的直方图均衡化
Oct 21 Python
基于Pytorch版yolov5的滑块验证码破解思路详解
Feb 25 Python
Python中IPYTHON入门实例
May 11 #Python
Python使用MONGODB入门实例
May 11 #Python
python学习数据结构实例代码
May 11 #Python
Python使用CMD模块更优雅的运行脚本
May 11 #Python
Python中DJANGO简单测试实例
May 11 #Python
python单元测试unittest实例详解
May 11 #Python
Python使用MYSQLDB实现从数据库中导出XML文件的方法
May 11 #Python
You might like
PHP下通过exec获得计算机的唯一标识[CPU,网卡 MAC地址]
2011/06/09 PHP
PHP 裁剪图片
2021/03/09 PHP
jquery.post用法之type设置问题
2014/02/24 Javascript
创建js对象和js类的方法汇总
2014/12/24 Javascript
NodeJS学习笔记之Connect中间件模块(二)
2015/01/27 NodeJs
JQuery判断checkbox是否选中及其它复选框操作方法合集
2015/06/01 Javascript
JavaScript中字符串(string)转json的2种方法
2015/06/25 Javascript
javascript中的previousSibling和nextSibling的正确用法
2015/09/16 Javascript
js中substring和substr两者区别和使用方法
2015/11/09 Javascript
JavaScript快速切换繁体中文和简体中文的方法及网站支持简繁体切换的绝招
2016/03/07 Javascript
jQuery源码分析之init的详细介绍
2017/02/13 Javascript
Webpack常见静态资源处理-模块加载器(Loaders)+ExtractTextPlugin插件
2017/06/29 Javascript
详解Nodejs mongoose
2018/06/10 NodeJs
记录一次完整的react hooks实践
2019/03/11 Javascript
jQuery实现B2B网站后台管理系统侧导航
2020/07/08 jQuery
Python的垃圾回收机制深入分析
2014/07/16 Python
python获得文件创建时间和修改时间的方法
2015/06/30 Python
Python读取Excel的方法实例分析
2015/07/11 Python
python 字典(dict)按键和值排序
2016/06/28 Python
Python基于回溯法子集树模板实现图的遍历功能示例
2017/09/05 Python
基于python list对象中嵌套元组使用sort时的排序方法
2018/04/18 Python
python使用opencv驱动摄像头的方法
2018/08/03 Python
python 实现一次性在文件中写入多行的方法
2019/01/28 Python
Python实现平行坐标图的两种方法小结
2019/07/04 Python
Python Django简单实现session登录注销过程详解
2019/08/06 Python
Python 实现Image和Ndarray互相转换
2020/02/19 Python
python Yaml、Json、Dict之间的转化
2020/10/19 Python
台湾SHOPRO购物行家:亚洲首创影视.3C.家电.优质购物平台
2018/05/07 全球购物
C语言中break与continue的区别
2012/07/12 面试题
餐饮投资计划书
2014/04/25 职场文书
2015年母亲节寄语
2015/03/23 职场文书
入伍通知书
2015/04/23 职场文书
幼儿园庆六一主持词
2015/06/30 职场文书
孕妇病假条怎么写
2015/08/17 职场文书
golang日志包logger的用法详解
2021/05/05 Golang
SQL基础的查询语句
2021/11/11 MySQL