Miller Rabin素性检测算法

。。。

#ifndef MILLER_RABIN_H
#define MILLER_RABIN_H

namespace rsa
{
    // 先约定数据类型为Number,日后若实现class Number,并重载了加减乘除等运算符号,则直接更换此处代码
    typedef unsigned __int64 Number;

    bool MillerRabinTest(const Number &N, const int &t);
}

#endif

。。。

#include "Miller_Rabin.h"

#include <ctime>
#include <set>

namespace rsa
{
    // 欧几里德除法求最大公约数
    static Number Gcd(const Number &a, const Number &b);
    // 产生一个witness
    static Number RandomWitness(const Number &N);
    // 模N群上做乘法运算
    static Number MultiplyMod(const Number &a, const Number &b, const Number &n);
    // 模N群上做指数运算
    static Number PowMod(const Number &base, const Number &pow, const Number &n);

    // 判断N是否是素数,即Miller Rabin素性检测
    bool MillerRabinTest(const Number &N, const int &loop)
    {
        if (N == 2)
        {
            return true;
        }

        if ((N & 1) == 0)
        {
            return false;
        }
        Number N_1 = N - 1;
        Number r = 0, u = 0;
        while ((N_1 & 1) == 0)
        {
            r++;
            N_1 >>= 1;
        }
        u = N_1;
        for (int i = 0; i < loop; i++)
        {
            Number a = RandomWitness(N);
            if (Gcd(a, N) != 1)
            {
                return false;
            }
            bool isStrongWitness = true;
            for (int j = 0; j < r; j++)
            {
                Number AnsTemp = PowMod(a, pow(2, j) * u, N);
                if ((AnsTemp == N - 1) || (AnsTemp == 1 && j == 0))
                {
                    isStrongWitness = false;
                    break;
                }
            }
            if (isStrongWitness == true)
            {
                return false;
            }
        }
        return true;
    }

    Number Gcd(const Number &p, const Number &q)
    {
        Number a = p > q ? p : q;
        Number b = p < q ? p : q;
        if (p == q)
        {
            return p;
        }
        else
        {
            while (b != 0)
            {
                a = a % b;
                std::swap(a, b);
            }
            return a;
        }
    }

    Number RandomWitness(const Number &N)
    {
        static bool isWork = false;
        if (isWork == false)
        {
            srand((unsigned)time(nullptr)); //用于保证是随机数
            isWork = true;
        }
        return rand() % (N - 2) + 2;
    }

    Number MultiplyMod(const Number &a, const Number &b, const Number &n)
    {
        return (a % n) * (b % n) % n;
    }

    Number PowMod(const Number &base, const Number &pow, const Number &n)
    {
        Number a = base;
        Number b = pow;
        Number c = 1;

        while (b != 0)
        {
            while ((b & 1) == 0)
            {
                b >>= 1;
                a = MultiplyMod(a, a, n);
            }
            b--;
            c = MultiplyMod(a, c, n);
        }

        return c;
    }
}

。。。

#include "Miller_Rabin.h"
#include <iostream>
#include <cmath>
using namespace std;

static bool isPrime(int n);

int main()
{
    for (int i = 2; i <= 1000000; i++)
    {
        bool mPrime = rsa::MillerRabinTest(i, 10);
        if (isPrime(i) != mPrime)
        {
            cout << i << endl;
        }
    }

    cout << endl;
    for (int i = 2; i <= 100; i++)
    {
        if (rsa::MillerRabinTest(i, 10))
        {
            cout << i << endl;
        }
    }

    system("pause");
    return 0;
}

bool isPrime(int n)
{
    for (int i = 2; i <= sqrt(n); i++)
    {
        if (n % i == 0)
        {
            return false;
        }
    }
    return true;
}

。。。

你可能感兴趣的:(Miller Rabin素性检测算法)