Python Miller Rabin 米勒-拉宾素性检验

Miller Rabin

米勒-拉宾素性检验是一种素数判定法则,利用随机化算法判断一个数是合数还是可能是素数。
卡内基梅隆大学的计算机系教授Gary Lee Miller首先提出了基于广义黎曼猜想的确定性算法,由于广义黎曼猜想并没有被证明,其后由以色列耶路撒冷希伯来大学的Michael O. Rabin教授作出修改,提出了不依赖于该假设的随机化算法。

来自 https://baike.baidu.com/item/米勒-拉宾素性检验/22719763

代码实现

import numpy as np


def get_random(i, j=None):
    if j == None:
        # 返回0-i的随机整数
        return np.random.randint(i + 1)
    if i > j:
        i, j = j, i
        # 获取i-j的随机整数
    return np.random.randint(i, j + 1)


def fast_power(base, power, n):
    result = 1
    tmp = base
    while power > 0:
        if power & 1 == 1:
            result = (result * tmp) % n
        tmp = (tmp * tmp) % n
        power = power >> 1
    return result


def Miller_Rabin(n, s):
    # 2是素数
    if n == 2:
        return True
    # n是偶数或小于2
    if n & 1 == 0 or n < 2:
        return False
    # n-1 = (2^s) m
    m, p = n - 1, 0
    while m & 1 == 0:
        m = m >> 1
        p += 1

    for _ in range(s):
        b = fast_power(get_random(2, n - 1), m, n)
        if b == 1 or b == n - 1:
            continue
        for __ in range(p - 1):
            b = fast_power(b, 2, n)
            if b == n - 1:
                break
        else:
            return False
    return True


if __name__ == '__main__':
    num = 50000
    s = 3
    prime = [x for x in range(2, num) if not [y for y in range(2, int(np.sqrt(x) + 1)) if x % y == 0]]
    result = []
    for i in range(num):
        flag = Miller_Rabin(i, s)
        if flag and i not in prime:
            print('error1: %d' % i)
        elif not flag and i in prime:
            print('error2: %d' % i)

代码复现了Miller-Rabin算法
代码测试方面预先计算出2-50000之间的素数,然后使用Miller-Rabin算法判断2-50000的数字是否为素数
打印说明:
'error1’表示Miller-Rabin错误判断为素数
'error2’表示Miller-Rabin错误判断为非素数

代码测试

测试1:
input:
s=1
output:

error1: 63
error1: 217
error1: 703
error1: 2977
error1: 2993
error1: 7033
error1: 7381
error1: 8911
error1: 9301
error1: 10963
error1: 12805
error1: 12871
error1: 20263
error1: 21097
error1: 26677
error1: 29539
error1: 31621
error1: 34861
error1: 42121
error1: 43553
error1: 44545
error1: 45795

测试2:
input:
s=2
output:

error1: 5461
error1: 45451

测试3:
input:
s=3
output:

None

结论

可以看出1次测试和2次测试都在计算上都出现了错误,从第3次测试开始没有出现错误,这也符合Miller-Rabin算法理论:
1.若在 s 次测试中没有找到见证者, MillerRabin(n, s)假定这是因为证据不存在,因此可认为 n 是素数。
2.当 s 足够大时,这个结果往往是对的,但在很少的情况下也可能由于选取 a 不合适而出错。

你可能感兴趣的:(Python,数据结构,算法,python,算法,miller-rabin算法)