日常篇:程序设计实验报告——异或加密,凯撒密码(不是完整代码)

在头歌平台上超过最大字符限制,无法提交。用博客网,语法一样。欢迎来我的园子逛逛~
第一部分
描述你的实验过程,包括代码编写、编译和运行。


第二部分(说明都在代码注释里)
提供加密和解密的不同示例,并说明测试结果。注意测试用例的选择,要涵盖不同情况。
2.1异或加密

  //=====begin=====
  int p_len = strlen(p_data); // 有效长度
  int key_len = strlen(key);


  if (key_len == 0) {
    key_len = 1;
    key[0] = '0'; // 空密钥默认设为二进制位0
  }

  // 循环条件i < p_len
  for (int i = 0; i < p_len; i++) {
    int p_bit = p_data[i] - '0'; // 明文位(0或1)
    int key_bit = key[i % key_len] - '0'; // 密钥位(循环使用)
    Encrypt[i] = (p_bit ^ key_bit) + '0'; 
  }
  Encrypt[p_len] = '\0'; 

  
  for (int i = 0; i < p_len; i++) {
    int encrypt_bit = Encrypt[i] - '0'; // 密文位转数字(0或1)
    int key_bit = key[i % key_len] - '0';
    Decrypt[i] = (encrypt_bit ^ key_bit) + '0'; 
  }
  Decrypt[p_len] = '\0'; 

  // 输出
  printf("Initial string: %s\n", p_data);
  printf("key string: %s\n", key);
  printf("Encrypt string: ");
  for (int k = 0; k < p_len; k++) 
  {
    printf("%c", Encrypt[k]);
  }

  printf("\n解密后的文本: ");
  for (int k = 0; k < p_len; k++) // 遍历明文长度,匹配解密结果
  {
    printf("%c", Decrypt[k]);
  }
  //======end======

测试结果

 Initial string: 10101110000
key string: 00000110101
Encrypt string: 10101000101
解密后的文本: 10101110000

2.2凯撒密码

// 加密函数,plaintext明文串,ci密文串,key密钥
/*凯撒密码的数学表示为:
加密公式:𝐶=(𝑃+𝐾)mod  26  
解密公式:𝑃=(𝐶−𝐾+26)mod  26  
其中:
𝐶:是密文字符的位置。
𝑃:是明文字符的位置。
𝐾:是密钥(移位量)。
26 是字母表的长度。
**补充**:
非字母字符不移位
200太大,遇到\0停止,条件判断
大小写区分函数
*/
void caesar_encrypt(const char plaintext[], char ciphertext[], int key) {
    //=====begin=====
    int i=0;
    key=(key%26+26)%26;

    while(plaintext[i]!='\0')
    {
        if(isupper(plaintext[i]))
        {
            ciphertext[i]=(plaintext[i]-'A'+key)%26+'A';
        }
        else if(islower(plaintext[i]))
        {
            ciphertext[i]=(plaintext[i]-'a'+key)%26+'a';
        }
        else
        {
            ciphertext[i]=plaintext[i];
        }
        i++;

    }
    ciphertext[i]='\0';

    //======end======
}

// 解密函数
void caesar_decrypt(const char ciphertext[], char plaintext[], int key) {
    //=====begin=====
        int i=0;
        key=(key%26+26)%26;
    while(ciphertext[i]!='\0')
    {
        if(isupper(ciphertext[i]))
        {
            plaintext[i]=(ciphertext[i]-'A'-key+26)%26+'A';
        }
        else if(islower(ciphertext[i]))
        {
            plaintext[i]=(ciphertext[i]-'a'-key+26)%26+'a';
        }
        else
        {
            plaintext[i]=ciphertext[i];
        }
        
        i++;
    }
    plaintext[i]='\0';
    
    //======end======
}

// 暴力破解函数,key从0~25变化,双层循环
void caesar_brute_force(const char ciphertext[]) {
    //=====begin=====
       int key;
    // 外层循环
    for (key = 0; key <= 25; key++) {
        char res[200];
        int i = 0;     
        
        // 内层循环
        while (ciphertext[i] != '\0') {
            if (isupper(ciphertext[i])) { 
                res[i] = (ciphertext[i] - 'A' - key + 26) % 26 + 'A';
            } else if (islower(ciphertext[i])) {
                res[i] = (ciphertext[i] - 'a' - key + 26) % 26 + 'a';
            } else { 
                res[i] = ciphertext[i];
            }
            i++;
        }
        res[i] = '\0'; // 添加结束符
        
        //Shift 0: Mjqqt Btwqi!
        printf("Shift %d: %s\n", key, res);
    }
    
    //======end======
}

测试结果

Encrypted: PQ34ERo;,#orusodrs
Decrypted: EF34TGd;,#dgjhdsgh
Shift 0: PQ34ERo;,#orusodrs
Shift 1: OP34DQn;,#nqtrncqr
Shift 2: NO34CPm;,#mpsqmbpq
Shift 3: MN34BOl;,#lorplaop
Shift 4: LM34ANk;,#knqokzno
Shift 5: KL34ZMj;,#jmpnjymn
Shift 6: JK34YLi;,#ilomixlm
Shift 7: IJ34XKh;,#hknlhwkl
Shift 8: HI34WJg;,#gjmkgvjk
Shift 9: GH34VIf;,#filjfuij
Shift 10: FG34UHe;,#ehkiethi
Shift 11: EF34TGd;,#dgjhdsgh
Shift 12: DE34SFc;,#cfigcrfg
Shift 13: CD34REb;,#behfbqef
Shift 14: BC34QDa;,#adgeapde
Shift 15: AB34PCz;,#zcfdzocd
Shift 16: ZA34OBy;,#ybecynbc
Shift 17: YZ34NAx;,#xadbxmab
Shift 18: XY34MZw;,#wzcawlza
Shift 19: WX34LYv;,#vybzvkyz
Shift 20: VW34KXu;,#uxayujxy
Shift 21: UV34JWt;,#twzxtiwx
Shift 22: TU34IVs;,#svywshvw
Shift 23: ST34HUr;,#ruxvrguv
Shift 24: RS34GTq;,#qtwuqftu
Shift 25: QR34FSp;,#psvtpest

第三部分
在AI帮助下,了解更多对称加密算法
在博客网上写有一篇关于密码的报告,其中实验关于国密sm234
练习篇:密码学基础


第四部分
报告最后一部分,要清晰阐述在实验过程中是如何使用AI工具的,以及AI在报告中的具体贡献

4.1在实验过程中

int key_bit = key[i % key_len] - '0'; // 密钥位(循环使用),查询ai为什么key不能运行,因为key是输入流。

fgets(p_data, sizeof(p_data), stdin); //那就不得不提到下一个问题,输入流是什么?stdin强制输入?吗?scanf?,sizeof(char)一个字符一字节,相当于个数。
//fgets(p_data, sizeof(p_data), stdin)的含义是:从stdin这个输入流中读取数据,存入p_data指向的内存,最多读取sizeof(p_data)-1个字符(因为fgets会自动在末尾加\0字符串结束符)。
//当程序执行到这行代码时,如果stdin流中没有可用数据(比如用户还没输入),程序会阻塞等待用户从键盘输入,直到用户按下回车键 —— 这是输入流的特性,而非 “强制输入”,只是程序需要等待输入才能继续执行。

 //这就不难解释这几行是干什么的了:
 //移除fgets可能读取的换行符
  if (p_data[strlen(p_data) - 1] == '\n') {
    p_data[strlen(p_data) - 1] = '\0';
  }
  
//这几行ASCII的操作
Encrypt[i] = (p_bit ^ key_bit) + '0'; //+ '0'定义了起始位置
ciphertext[i]=(plaintext[i]-'A'+key)%26+'A';//plaintext[i]-'A'计算相对位置,+'A'同上

//每个输入后,为什么要加\0
ciphertext[i]='\0';//C 语言没有原生的 “字符串类型”,而是通过 **“字符数组 + '\0' 结束符”来模拟字符串。该实验没有规定**到底要输入多少个字符**,为了防止内存读取溢出,一定要加一个\0。

//实验最后是输出字符串%s,那么用for输出,和用%s输出的输入要求?
printf("Shift %d: %s\n", key, res);//简单一点
//使用%s一次性输出,数组类型必用char,,输入%c,后续要加\0;输入%s,不用加
//普通printf
for(int i=0;i<200;i++)
{
        printf("Shift %d: ", key);
        for (int k = 0; res[k] != '\0'; k++) {
            printf("%c", res[k]); 
        }
        // 换行,保证每个key的结果占一行
        printf("\n");
}

4.2在报告中
回顾markdown语法

posted @ 2025-12-13 12:38  xxxl_R  阅读(8)  评论(0)    收藏  举报