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 相关文章推荐
apache部署python程序出现503错误的解决方法
Jul 24 Python
python 3.6 +pyMysql 操作mysql数据库(实例讲解)
Dec 20 Python
Python中反射和描述器总结
Sep 23 Python
利用anaconda保证64位和32位的python共存
Mar 09 Python
django 微信网页授权认证api的步骤详解
Jul 30 Python
Django查询优化及ajax编码格式原理解析
Mar 25 Python
pyautogui自动化控制鼠标和键盘操作的步骤
Apr 01 Python
python 数据分析实现长宽格式的转换
May 18 Python
在pycharm中创建django项目的示例代码
May 28 Python
基于logstash实现日志文件同步elasticsearch
Aug 06 Python
Python 用户输入和while循环的操作
May 23 Python
使用python生成大量数据写入es数据库并查询操作(2)
Sep 23 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
mysql 搜索之简单应用
2007/04/27 PHP
php数组函数序列之array_values() 获取数组元素值的函数与方法
2011/10/30 PHP
PHP中设置时区,记录日志文件的实现代码
2013/01/07 PHP
PHP使用mysql与mysqli连接Mysql数据库用法示例
2016/07/07 PHP
PHP SFTP实现上传下载功能
2017/07/26 PHP
PHP使用ajax的post方式下载excel文件简单示例
2019/08/06 PHP
laravel model 两表联查示例
2019/10/24 PHP
JavaScript中两个感叹号的作用说明
2011/12/28 Javascript
jQuery事件之键盘事件(ctrl+Enter回车键提交表单等)
2014/05/11 Javascript
jquery使用animate方法实现控制元素移动
2015/03/27 Javascript
JavaScript实现数字数组按照倒序排列的方法
2015/04/06 Javascript
JQuery zClip插件实现复制页面内容到剪贴板
2015/11/02 Javascript
JS简单实现点击复制链接的方法
2016/08/03 Javascript
javascript数字验证的实例代码(推荐)
2016/08/20 Javascript
easyui取消表单实时验证,提交时统一验证的简单实例
2016/11/07 Javascript
Easyui笔记2:实现datagrid多行删除的示例代码
2017/01/14 Javascript
微信小程序 ES6Promise.all批量上传文件实现代码
2017/04/14 Javascript
vue.js实现单选框、复选框和下拉框示例
2017/07/18 Javascript
ES6 Symbol数据类型的应用实例分析
2019/06/26 Javascript
如何在Angular8.0下使用ngx-translate进行国际化配置
2019/07/24 Javascript
jQuery实现弹幕特效
2019/11/29 jQuery
JS判断数组是否包含某元素实现方法汇总
2020/06/24 Javascript
用Python创建声明性迷你语言的教程
2015/04/13 Python
Python3.6日志Logging模块简单用法示例
2018/06/14 Python
pytorch中tensor的合并与截取方法
2018/07/26 Python
Python递归函数实例讲解
2019/02/27 Python
Python实现TCP通信的示例代码
2019/09/09 Python
Python多线程爬取豆瓣影评API接口
2019/10/22 Python
python实现大学人员管理系统
2019/10/25 Python
实例代码讲解Python 线程池
2020/08/24 Python
python绘制高斯曲线
2021/02/19 Python
使用tkinter实现三子棋游戏
2021/02/25 Python
深入浅析HTML5中的article和section的区别
2018/05/15 HTML / CSS
电子信息科学专业自荐信
2014/01/30 职场文书
公务员党员评议表自我鉴定
2014/09/14 职场文书
联想win10摄像头打不开怎么办?win10笔记本摄像头打不开解决办法
2022/04/08 数码科技