教学服务系统

 找回密码
 立即注册
搜索
查看: 531|回复: 4

信息计算2019级2班10号蔡冉平

[复制链接]

8

主题

24

帖子

116

积分

注册会员

Rank: 2

积分
116
发表于 2022-4-22 14:40:00 | 显示全部楼层 |阅读模式
4月19日
4.1——4.4

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

8

主题

24

帖子

116

积分

注册会员

Rank: 2

积分
116
 楼主| 发表于 2022-4-22 14:40:39 | 显示全部楼层
4月22日
4.4——4.7

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

8

主题

24

帖子

116

积分

注册会员

Rank: 2

积分
116
 楼主| 发表于 2022-4-29 20:53:26 | 显示全部楼层
2022年4月29日

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

8

主题

24

帖子

116

积分

注册会员

Rank: 2

积分
116
 楼主| 发表于 2022-5-3 11:18:05 | 显示全部楼层
本帖最后由 信计2班蔡冉平 于 2022-5-20 15:43 编辑
  1. <div class="blockcode"><blockquote> #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <time.h>
  4. #include <string.h>
  5.    
  6. #define ACCURACY 5
  7. #define SINGLE_MAX 250
  8. #define EXPONENT_MAX 1
  9. #define BUF_SIZE 1024
  10. //计算a^b mod c
  11. int modpow( long a, long b, int c) {
  12.      int res = 1;
  13.      while(b > 0) {
  14.          if(b & 1) {
  15.             res = (res * a) % c;
  16.          }
  17.          b = b >> 1;
  18.          a = (a * a) % c;
  19.      }
  20.      return res;
  21. }  
  22. //计算Jacobi符号(a,n)
  23. int jacobi(int a, int n) {
  24.      int twos, temp;
  25.      int mult = 1;
  26.      while(a > 1 && a != n) {
  27.          a = a % n;
  28.          if(a <= 1 || a == n) break;
  29.          twos = 0;
  30.          while(a % 2 == 0 && ++twos) a /= 2; //减去2的倍数
  31.          if(twos > 0 && twos % 2 == 1) mult *= (n % 8 == 1 || n % 8 == 7) * 2 - 1;
  32.         if(a <= 1 || a == n) break;
  33.          if(n % 4 != 1 && a % 4 != 1) mult *= -1;//翻转系数
  34.          temp = a;
  35.          a = n;
  36.          n = temp;
  37.      }
  38.      if(a == 0) return 0;
  39.      else if(a == 1) return mult;
  40.      else return 0;
  41. }
  42. //检查a是否为n的欧拉见证
  43. int solovayPrime(int a, int n) {
  44.     int x = jacobi(a, n);
  45.      if(x == -1) x = n - 1;
  46.      return x != 0 && modpow(a, (n - 1)/2, n) == x;
  47. }
  48. //用k的精度检查n是否可能是素数
  49. int probablePrime(int n, int k) {
  50.      if(n == 2) return 1;
  51.      else if(n % 2 == 0 || n == 1) return 0;
  52.      while(k-- > 0) {
  53.          if(!solovayPrime(rand() % (n - 2) + 2, n)) return 0;
  54.      }
  55.      return 1;
  56. }
  57. // 在3和(n-1)之间找一个随机素数
  58. int randPrime(int n) {
  59.      int prime = rand() % n;
  60.      n += n % 2;
  61.      prime += 1 - prime % 2;
  62.      while(1) {
  63.          if(probablePrime(prime, ACCURACY)) return prime;
  64.          prime = (prime + 2) % n;
  65.      }
  66. }
  67. //计算gcd(a,b)
  68. int gcd(int a, int b) {
  69.      int temp;
  70.      while(b != 0) {
  71.          temp = b;
  72.          b = a % b;
  73.          a = temp;
  74.      }
  75.      return a;
  76. }

  77. //在3和n-1之间找到随机指数x,使得gcd(x,phi)=1,这种分布同样不接近制服
  78.   int randExponent(int phi, int n) {
  79.      int e = rand() % n;
  80.      while(1) {
  81.         if(gcd(e, phi) == 1) return e;
  82.          e = (e + 1) % n;
  83.         if(e <= 2) e = 3;
  84.      }
  85. }

  86. // 用扩展欧几里得法计算n^-1 mod m

  87. int inverse(int n, int modulus) {
  88.      int a = n, b = modulus;
  89.     int x = 0, y = 1, x0 = 1, y0 = 0, q, temp;
  90.     while(b != 0) {
  91.         q = a / b;
  92.          temp = a % b;
  93.          a = b;
  94.          b = temp;
  95.          temp = x; x = x0 - q * x; x0 = temp;
  96.         temp = y; y = y0 - q * y; y0 = temp;
  97.      }
  98.      if(x0 < 0) x0 += modulus;
  99.      return x0;
  100. }
  101. //将文件fd读入准备加密的字节数组,数组将填充零,知道它划分每个块加密的字节数,返回读取的字节数
  102. int readFile(FILE* fd, char** buffer, int bytes) {
  103.      int len = 0, cap = BUF_SIZE, r;
  104.      char buf[BUF_SIZE];
  105.      *buffer = (char *)malloc(BUF_SIZE * sizeof(char));
  106.     while((r = fread(buf, sizeof(char), BUF_SIZE, fd)) > 0) {
  107.         if(len + r >= cap) {
  108.              cap *= 2;
  109.            *buffer = (char *)realloc(*buffer, cap);
  110.         }
  111.         memcpy(&(*buffer)[len], buf, r);
  112.          len += r;
  113.     }
  114. //将最后一个带有零的块插入密码的信号端。 如果没有多余,则额外增加一个
  115.      if(len + bytes - len % bytes > cap) *buffer = (char *)realloc(*buffer, len + bytes - len % bytes);
  116.      do {
  117.         (*buffer)[len] = '\0';
  118.          len++;
  119.      }
  120.      while(len % bytes != 0);
  121.      return len;
  122. }
  123. //c = m^e mod n使用公共指数和模量对消息m进行编码,c = m^e Mod n
  124. int encode(int m, int e, int n) {
  125.     return modpow(m, e, n);
  126. }
  127. //m = c^d mod n,用私有指数和公共模量解码密码c,m = c^d Mod
  128.   int decode(int c, int d, int n) {
  129.       return modpow(c, d, n);
  130.   }
  131.    
  132. // 使用公钥(指数、模数)对给定长度的消息进行编码),得到的数组将是大小为len/字节,每个索引是由m=(m1m2*128m3*128^2.)给出的“字节”连续字符的加密,编码=m^指数mod模量
  133. int* encodeMessage(int len, int bytes, char* message, int exponent, int modulus) {
  134.      int *encoded = (int *)malloc((len/bytes) * sizeof(int));
  135.     int x, i, j;
  136.     for(i = 0; i < len; i += bytes) {
  137.         x = 0;
  138.         for(j = 0; j < bytes; j++) x += message[i + j] * (1 << (7 * j));
  139.          encoded[i/bytes] = encode(x, exponent, modulus);
  140. #ifndef MEASURE
  141.          printf("%d ", encoded[i/bytes]);
  142. #endif
  143.      }
  144.     return encoded;
  145. }
  146. //使用私钥(指数、模数)解码给定长度的密码), 每个加密的数据包应该按照编码消息表示“字节”字符,返回的消息大小为len*字节。

  147. int* decodeMessage(int len, int bytes, int* cryptogram, int exponent, int modulus) {
  148.      int *decoded = (int *)malloc(len * bytes * sizeof(int));
  149.     int x, i, j;
  150.     for(i = 0; i < len; i++) {
  151.         x = decode(cryptogram[i], exponent, modulus);
  152.         for(j = 0; j < bytes; j++) {
  153.             decoded[i*bytes + j] = (x >> (7 * j)) % 128;
  154. #ifndef MEASURE
  155.             if(decoded[i*bytes + j] != '\0') printf("%c", decoded[i*bytes + j]);
  156. #endif
  157.          }
  158.     }
  159.     return decoded;
  160. }
  161.   //系统降级的主要方法。 设置素数p,q,并开始编码和解码“text.txt”中给出的消息;
  162. int main(void) {
  163.      int p, q, n, phi, e, d, bytes, len;
  164.     int *encoded, *decoded;
  165.     char *buffer;
  166.    FILE *f;
  167.      srand(time(NULL));
  168.      while(1) {
  169.         p = randPrime(SINGLE_MAX);
  170.         printf("生成第一个随机素数, p = %d ", p);
  171.         getchar();
  172.         q = randPrime(SINGLE_MAX);
  173.                 printf("生成第二个随机素数, q = %d  ", q);
  174.       getchar();
  175.       n = p*q;
  176.        printf("计算p和q的乘积n, n = p * q = %d ", n);
  177.         if(n < 128) {
  178.             printf("模数小于 128,不能编码单个字节。 再试一次\n");
  179.             getchar();
  180.         }
  181.         else break;
  182.      }
  183.    if(n >> 21) bytes = 3;
  184.     else if(n >> 14) bytes = 2;
  185.     else bytes = 1;
  186.      getchar();
  187.     phi = (p - 1) * (q - 1);
  188.     printf("计算欧拉函数的值phi, phi = %d ", phi);
  189.    getchar();
  190.    e = randExponent(phi, EXPONENT_MAX);
  191.    printf("选取一个随机素数e, e = %d \n获得公钥 (%d, %d)  ", e, e, n);
  192.     getchar();
  193.     d = inverse(e, phi);
  194.      printf("计算模反元素d, d = %d \n获得密钥 (%d, %d)  ", d, d, n);
  195.      getchar();
  196.    printf("打开文件 “text.txt” 用于读取信息");
  197.     f = fopen("text.txt", "r");
  198.     if(f == NULL) {
  199.         printf("无法打开文件 “text.txt” 它存在吗?\n");
  200.         return EXIT_FAILURE;
  201.      }
  202.      len = readFile(f, &buffer, bytes);
  203.    fclose(f);
  204.    printf("文件 “text.txt” 读取成功, 读取到%d字节. 以%d字节的字节流编码", len, bytes);
  205.     getchar();
  206.     printf("加密得密文为:\n");
  207.     encoded = encodeMessage(len, bytes, buffer, e, n);
  208.     printf("编码成功完成 \n");
  209.     getchar();
  210.    printf("正在解码编码的信息 .........\n ");
  211.    getchar();
  212.     printf("解码得明文为:\n");
  213.     decoded = decodeMessage(len/bytes, bytes, encoded, d, n);
  214.         printf("\n");
  215.     free(encoded);
  216.     free(decoded);
  217.     free(buffer);
  218.     return EXIT_SUCCESS;
  219. }
复制代码

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

8

主题

24

帖子

116

积分

注册会员

Rank: 2

积分
116
 楼主| 发表于 2022-5-3 11:20:12 | 显示全部楼层
2022年5月3日
4.8—4.11

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

教学服务系统

GMT+8, 2025-4-30 14:32 , Processed in 0.017199 second(s), 19 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表