(一)欧几里得函数
1.原理
图片来自:《信息安全数学基础-算法,应用与实践》(第二版)
2.伪码
图片来自:《信息安全数学基础-算法,应用与实践》(第二版)
3.C++代码
#pragma once
#include<iostream>
#include<time.h>
using namespace std;
typedef long long int ll;
ll GCD(ll a, ll b)//求两个数的最大公因数
{
//输入为非负数
if (a < 0 || b < 0)
{
cout << "请输入非负数";
}
//a小于b就交换一下
ll temp;
if (a < b)
{
temp = a;
a = b;
b = temp;
}
while (b != 0)
{
ll r = a % b;
a = b;
b = r;
}
return a;
}
void Euclid_Test()//测试函数
{
ll a, b;
cin >> a >> b;
clock_t starttime, endtime;
starttime = clock();
cout << GCD(a, b);
endtime = clock();
cout << endl << "所用的时间为:" << (double)(endtime - starttime) / CLOCKS_PER_SEC << "s" << endl;
}
(二)扩展欧几里得函数
1.原理
图片来自:《信息安全数学基础-算法,应用与实践》(第二版)
2.伪码
图片来自:《信息安全数学基础-算法,应用与实践》(第二版)
3.逆元伪码
图片来自:《信息安全数学基础-算法,应用与实践》(第二版)
4.C++代码
#pragma once
#include<iostream>
#include<time.h>
using namespace std;
typedef long long int ll;
bool ExtendedEuclid(ll a, ll m)//输入两个数,第一个数为要求逆元的数,第二个数为模数
{
//使用非负整数
if (a < 0 || m < 0)
{
cout << "请输入非负整数!";
return false;
}
int flag = 0;//标记a,m是否交换
if (a > m)
{
ll temp = a;
a = m;
m = temp;
flag = 1;
}
ll A1 = 1, A2 = 0, A3 = m;
ll B1 = 0, B2 = 1, B3 = a;
while (true)
{
if (B3 == 0)
{
cout << "没有逆元!";
return false;
}
if (B3 == 1)
{
if (flag == 0)//a,m没有进行交换
{
cout << a << "的逆元为" << B2;
}
if (flag == 1)
{
cout << m << "的逆元为" << B1;
}
return true;
}
ll Q = A3 / B3;
ll temp1= A1 - Q * B1;
ll temp2 = A2 - Q * B2;
ll temp3 = A3 - Q * B3;
A1 = B1; A2 = B2; A3 = B3;
B1 = temp1; B2 = temp2; B3 = temp3;
}
}
void ExtendedEuclid_Test()
{
clock_t starttime, endtime;
starttime = clock();
ExtendedEuclid(121, 169);
endtime = clock();
cout << endl << "所用的时间为:" << (double)(endtime - starttime) / CLOCKS_PER_SEC << "s" << endl;
}