• 素性测试


    测试一个数是否为素数。

    当这个数很小时,我们当然可以用试除法(用2到sqrt(N)看能否整除N)来做素性测试。

    当这个数很大时,例如1024bit即1~2^1024,这个方法就显得效率太低。考虑一个数有k位,每增加一位,N增大一倍,试除法此时是指数级别的算法。

    对于大整数的素性测试,一般用Miller-Rabin算法。它是一个基于概率的算法,是费马小定理(若n是一个素数,a^(n-1) mod n == 1;反之,n有可能是一个素数)的一个改进。

    理论基础:若n是一个素数,a<n 满足 a^2 mod n = 1 当且仅当 a mod n = 1 或 a mod n = -1(即a mod n = n-1)。取n = q * 2^k,即若n为素数以下两个条件必有一个满足:1. a^q ≡ 1(mod n);2. for j = 0~k, a^(q*2^j) ≡ n-1 (mod n)。(因为正负1的平方必为1)

    更详细的理论解释请看CANS的P252.http://book.douban.com/subject/5372307/

    另外,为了提高效率,这个算法需要用到快速幂取模算法。http://www.cnblogs.com/7hat/p/3398394.html

    算法的时间复杂度比试除法显然要高得多。注意到算法只有一个循环系数k,调用的快速幂取模也是和k有关,是多项式级别的算法。

    下面给出python代码,是因为python直接支持大整数,看起来会更加简单。

    import random
    
    """
    e = e0*(2^0) + e1*(2^1) + e2*(2^2) + ... + en * (2^n)
    
    b^e = b^(e0*(2^0) + e1*(2^1) + e2*(2^2) + ... + en * (2^n))
        = b^(e0*(2^0)) * b^(e1*(2^1)) * b^(e2*(2^2)) * ... * b^(en*(2^n)) 
    
    b^e mod m = ((b^(e0*(2^0)) mod m) * (b^(e1*(2^1)) mod m) * (b^(e2*(2^2)) mod m) * ... * (b^(en*(2^n)) mod m) mod m
    """
    def fastExpMod(b, e, m):
        result = 1
        while e != 0:
            if (e&1) == 1:
                # ei = 1, then mul
                result = (result * b) % m
            e >>= 1
            # b, b^2, b^4, b^8, ... , b^(2^n)
            b = (b*b) % m
        return result
    
    def primeTest(n):
        q = n - 1
        k = 0
        #Find k, q, satisfied 2^k * q = n - 1
        while q % 2 == 0:
            k += 1;
            q /= 2
        a = random.randint(2, n-2);
        #If a^q mod n= 1, n maybe is a prime number
        if fastExpMod(a, q, n) == 1:
            return "inconclusive"
        #If there exists j satisfy a ^ ((2 ^ j) * q) mod n == n-1, n maybe is a prime number
        for j in range(0, k):
            if fastExpMod(a, (2**j)*q, n) == n - 1:
                return "inconclusive"
        #a is not a prime number
        return "composite"
    print primeTest(93450983094850938450983409621);
    Python
  • 相关阅读:
    图表插件echars的使用案例
    安装Eclipse
    ef 更新数据库
    webapi Route 特性
    WebSite下创建webapi
    C# 泛型约束
    Session共享
    ubuntu eclipse 无法打开
    C# TreeView 连续点击 不触发AfterCheck事件
    ef 仓储模式 Redis
  • 原文地址:https://www.cnblogs.com/7hat/p/3400831.html
Copyright © 2020-2023  润新知