信安数学基础作业

爱拉托斯散算法

【C++代码实现】

#include<iostream>
#include<math.h>
using namespace std;
int main() {
    long long int n;
    cout << "请输入一个正整数N:\n";
    cin >> n;
    cout << "不超过N的素数有:\n";
    long long int* number = new long long int[n + 1];
    bool* del = new bool[n + 1];
    for (int i = 2; i <= n; i++) {
       number[i] = i;
       del[i] = false;// 初始化数组,false表示为素数未被删除
    }
    // 删除算法
    for (int i = 2; i <= sqrt(n); i++) {
       if (del[i] == false) {
           for (int j = number[i] * 2; j <= n; j += number[i]) {
              del[j] = true; // 如果此时number[i]为素数,则开始删除其倍数,若不是素数则不会进入该循环
           }
       }
    }
    int flag = 1;
    // 打印输出小于N的素数,每一行输出十个数字
    for (int i = 2; i <= n; i++) {
       if (del[i] == false) {
           if (flag++ != 10)
              cout << number[i] << "\t";
           else {
              flag = 1;
              cout << number[i] << endl;
           }
       }
    }
    return 0;
}

【编译结果】

满足爱拉托斯散算法删除结果

两位大整数的和与积

【C++代码实现】

#include<iostream>
#include<vector>
using namespace std;
int main()
{
    string s1, s2;
    vector<int> num1; // 输入的大整数1
    vector<int> num2; // 输入的大整数2
    vector<int> num_add;// 大整数求和结果
    vector<int> num_mul;// 大整数求积结果
    cout << "请输入两个小于100位的大整数:\n";
    cin >> s1 >> s2;
    int len1 = s1.length();
    int len2 = s2.length();
    int len_max, len_min, flag = 0;
    if (len1 > len2) {
       len_max = len1;
       len_min = len2;
       flag = 1;
    }
    else {
       len_max = len2;
       len_min = len1;
    }
    for (int i = len1 - 1; i >= 0; i--) {
       int a = s1[i] - 48;
       num1.push_back(a);
    }
    for (int i = len2 - 1; i >= 0; i--) {
       int a = s2[i] - 48;
       num2.push_back(a);
    }
    int d = 0, a = 0;
    //加法操作
    for (int i = 0; i < len_max; i++) {
       if (i < len_min) {
           a = num1[i] + num2[i] + d;
           if (a >= 10) {
              d = 1;
              a = a - 10;
           }
           else
              d = 0;
           num_add.push_back(a);
       }
       else {
           if (flag == 1) {
              a = num1[i] + d;
              if (a >= 10) {
                  d = 1;
                  a = a - 10;
              }
              else
                  d = 0;
              num_add.push_back(a);
           }
           else {
              a = num2[i] + d;
              if (a >= 10) {
                  d = 1;
                  a = a - 10;
              }
              else
                  d = 0;
              num_add.push_back(a);
              d = 0;
           }
       }
    }
    if (d == 1) num_add.push_back(d);
    cout << "两位大整数和为:\n";
    for (int i = num_add.size() - 1; i >= 0; i--) {
       cout << num_add[i];
    }
    //乘法操作
    d = 0;
    for (int i = 0; i < len1; i++) {
       if (d != 0) {
           num_mul.push_back(d);
           d = 0;
       }
       for (int j = 0; j < len2; j++) {
           int k = i + j;
           a = num1[i] * num2[j] + d;
           if (a >= 10) {
              d = a / 10;
              a = a % 10;
           }
           else
              d = 0;
           if (k >= num_mul.size())
              num_mul.push_back(a);
           else
              num_mul[k] += a;
       }
    }
    if (d != 0) num_mul.push_back(d);
    for (int i = 0; i < num_mul.size(); i++) {
       if (num_mul[i] >= 10) {
           num_mul[i + 1] += num_mul[i] / 10;
           num_mul[i] = num_mul[i] % 10;
       }
    }
    cout << "\n两位大整数积为:\n";
    for (int i = num_mul.size() - 1; i >= 0; i--) {
       cout << num_mul[i];
    }
    return 0;
}

【编译结果】


满足两位大整数的和与积结果

模P二次剩余(欧拉判别法)

【实验原理】

【C++代码实现】

#include<iostream>
using namespace std;
int main()
{
    cout << "请输入一个不为0的整数a和一个奇素数p:\n";
    int a, p;
    cin >> a >> p;
    int n = (p - 1) / 2, tmp = 1;
    for (int i = 0; i < n; i++)
    {
       tmp = (tmp * a) % p;
    }
    if (tmp == 1) cout << a << " 是模 " << p << " 的平方剩余。\n";
    if (tmp == p - 1) cout << a << " 是模 " << p << " 的平方非剩余。\n";
    return 0;
}

【编译结果】

结果正确。

Fermat素性检测和爱拉托散筛法素性检测

【实验原理】

Fermat素性检测:

爱拉托散筛法:

【C++代码实现】

#include <iostream>
#include <cstdlib>
#include <ctime>
#include <math.h>
using namespace std;
int gcd(int x, int y) {
    int t;
    // 广义欧几里得除法
    while (y) {
       t = x;
       x = y;
       y = t % y;
    }
    return x;
}
int p; // 待检测的奇数
// Fermat素性检测
int Fermat() {
    int flag = 1; // p为素数判断标志
    // 对rand函数进行初始化
    unsigned seed;
    seed = time(0);
    srand(seed);
    // 进行10次判断,正确概率为 1023/1024
    for (int i = 0; i < 10; i++) {
       int n = p;
       // 随机抽取b(0<b<n)
       int b = rand() % (n - 1) + 1;
       // 利用广义欧几里得除法算得b和p的最大公因数
       int d = gcd(b, n);
       if (d > 1) {
           flag = 0;
           break;
       }
       else {
           long long int r = 1;
           while (n != 1) {
              r = (r * b) % p;
              n--;
           }
           if (r != 1) {
              flag = 0;
              break;
           }
       }
    }
    return flag;
}
// 爱拉托散筛法素性检测
int al() {
    int flag = 0, n = p+1; // flag为素数判断标志
    int* number = new int[n + 1];
    bool* del = new bool[n + 1];
    for (int i = 2; i <= n; i++) {
       number[i] = i;
       del[i] = false;// 初始化数组,false表示为素数未被删除
    }
    // 删除算法
    for (int i = 2; i <= sqrt(n); i++) {
       if (del[i] == false) {
           for (int j = number[i] * 2; j <= n; j += number[i]) {
              del[j] = true; // 如果此时number[i]为素数,则开始删除其倍数,若不是素数则不会进入该循环
           }
       }
    }
    for (int i = 2; i <= n; i++) {
       if (del[i] == false && number[i] == p) {
           flag = 1;
           break;
       }
    }
    return flag;
}
int main()
{
    cout << "请输入一个奇数p:\n";
    cin >> p;
    cout << "Fermat素性检测结果:\n";
    if (Fermat() == 1) cout << p << "是一个素数!\n";
    else cout << p << "不是一个素数!\n";
    cout << "爱拉托散筛法素性检测结果:\n";
    if (al() == 1) cout << p << "是一个素数!\n";
    else cout << p << "不是一个素数!\n";
    return 0;
}

【编译结果】

【效率分析】

 对于Fermat素性检测,为概率检测,利用循环进行了10次判断,正确概率为 1023/1024。时间复杂度主要由计算r=b^n-1 (mod p)时产生,利用while循环,时间复杂度为O(n),又由于进行了10次判断,故时间复杂度为O(10n)。只用了几个变量存储中间数据,空间复杂度为O(c)。
 对于爱拉托散筛法素性检测,为确定性检测。时间复杂度主要由删除算法产生,利用了循环内再套用循环,故时间复杂度为O(n^2)。用了两组长度为n+1的数组来记录数据及是否删除,空间复杂度为O(2n)。
 经过比较,我们发现,Fermat素性检测虽然为概率检测,但时间复杂度远低于爱拉托散筛法素性检测,对于比较大的奇数,也是Fermat素性检测更占优势。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我是蒸饺吖~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值