首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Rabin-Miller强伪素测试实现将不起作用

Rabin-Miller强伪素测试实现将不起作用
EN

Stack Overflow用户
提问于 2013-01-31 04:39:35
回答 4查看 9.4K关注 0票数 5

今天我一直在尝试实现Rabin-Miller强伪素性测试。

使用Wolfram Mathworld作为参考,第3-5行总结了我的代码。

然而,当我运行程序时,它告诉我(有时)质数(即使是5,7,11这样的低值)也不是质数。我已经看了很长一段时间的代码,找不出哪里出了问题。

为了寻求帮助,我看过这个网站和许多其他网站,但大多数都使用另一种定义(可能是相同的,但由于我对这种数学不熟悉,我看不到明显的联系)。

我的代码:

代码语言:javascript
复制
import random

def RabinMiller(n, k):

    # obviously not prime
    if n < 2 or n % 2 == 0:
        return False

    # special case        
    if n == 2:
        return True

    s = 0
    r = n - 1

    # factor n - 1 as 2^(r)*s
    while r % 2 == 0:
        s = s + 1
        r = r // 2  # floor

    # k = accuracy
    for i in range(k):
        a = random.randrange(1, n)

        # a^(s) mod n = 1?
        if pow(a, s, n) == 1:
            return True

        # a^(2^(j) * s) mod n = -1 mod n?
        for j in range(r):
            if pow(a, 2**j*s, n) == -1 % n:
                return True

    return False

print(RabinMiller(7, 5))

这与Mathworld给出的定义有什么不同?

EN

回答 4

Stack Overflow用户

发布于 2013-01-31 05:19:30

除了Omri Barel所说的之外,for循环还有一个问题。如果找到一个通过测试的a,您将返回true。然而,所有的a都必须通过测试才能使n成为可能的素数。

票数 4
EN

Stack Overflow用户

发布于 2013-01-31 05:05:40

我想知道这段代码:

代码语言:javascript
复制
# factor n - 1 as 2^(r)*s
while r % 2 == 0:
    s = s + 1
    r = r // 2  # floor

n = 7为例。所以n - 1 = 6。我们可以将n - 1表示为2^1 * 3。在本例中为r = 1s = 3

但是上面的代码发现了一些其他东西。它以r = 6开头,所以r % 2 == 0。最初,在一次迭代之后,我们得到了s = 1r = 3。但是现在r % 2 != 0和循环终止了。

我们最终得到了s = 1r = 3,这显然是不正确的:2^r * s = 8

您不应该在循环中更新s。相反,您应该计算可以除以2的次数(这将是r),除法后的结果将是s。在n = 7n - 1 = 6的例子中,我们可以将它除以一次(所以是r = 1),除法之后我们得到3(所以是s = 3)。

票数 2
EN

Stack Overflow用户

发布于 2013-01-31 05:52:50

以下是我的版本:

代码语言:javascript
复制
# miller-rabin pseudoprimality checker

from random import randrange

def isStrongPseudoprime(n, a):
    d, s = n-1, 0
    while d % 2 == 0:
        d, s = d/2, s+1
    t = pow(a, d, n)
    if t == 1:
        return True
    while s > 0:
        if t == n - 1:
            return True
        t, s = pow(t, 2, n), s - 1
    return False

def isPrime(n, k):
    if n % 2 == 0:
        return n == 2
    for i in range(1, k):
        a = randrange(2, n)
        if not isStrongPseudoprime(n, a):
            return False
    return True

如果你想了解更多关于素数编程的知识,我在我的博客上谦虚地推荐this essay

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14613304

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档