七喜喝可乐 2022-06-06 16:33 采纳率: 100%
浏览 135
已结题

大学数据结构实践周问题,求解!

某公司有一份机密文件,是由英文字母(大小写)、英文逗号、英文句点、空格和回车等符号组成的文件名为Jimi.txt的文本文件。公司为了保证文件不被泄密,要求技术人员将文件中的每个字符都用一个二进制位串进行加密,需要时能进行解密,但必须保证加密后的文件不能过大,且对加密的文件进行解密后与原文件必须完全一致。菜单包括: 1.显示原文本文?件; 2.文本文件加密; 3.显示字符编码; 4.显示加密文件;5.文本文件解密;6.显示解密文件;7.退出系统。使用C语言或C++

  • 写回答

4条回答 默认 最新

  • Run808 2022-06-07 08:42
    关注

    #include<stdio.h>
    #include<stdlib.h>
    #include<math.h>
    #include<string.h>
    #define SIZE 99
    typedef struct student//自定义结构体变量类型student
    {
    char stn[SIZE];//student number
    char fn[SIZE];//first name
    char ln[SIZE];//last name
    char gen[SIZE];//gender
    char maj[SIZE];//major
    char aod[SIZE];//address of dormitory
    char nor[SIZE];//names of roommates
    }student;
    void encrypt(char* p1, int* p2, int a, int b, int* size, int* countc);
    //加密函数 char* p1加密前的字符串 int* p2加密后的字符串的ascll码 a,b加密方程的参数 (int* size)p2的元素个数,int* countc 记录汉字出现的位置
    void decrypt(char* p1, int* p2, int a, int b, int size, int* countc);
    //解密函数 char* p1解密后的字符串 int* p2解密前的字符串的ascll码 a,b加密方程的参数 (int* size)p2的元素个数,int* countc 记录汉字出现的位置
    int main()
    {
    student a = { 0 }; //结构体初始化,用于存储信息
    FILE* pf; //文件指针
    char* address = NULL; //文件名以及存储路径
    char* str = NULL, * fstr = NULL; //str 原自我介绍字符串(明文) fster解密后的自我介绍字符串
    int charge, a1, b1, size = 0; //charge记录是否有names of roommates a1b1加密方程的参数 size自我介绍字符串的字符个数
    long length;//记录自我介绍前(即个人信息后)的指针位置,方便第二次读取自我介绍
    int* str_int, * fstr_int, * countc;//str_int 加密后的字符串的ascll码们 fstr_int 从文件中读入的已经加密过的字符串的ascll码们
    address = (char
    )malloc(1000);//分配内存
    str = (char
    )malloc(10000);
    fstr = (char*)malloc(10000);
    str_int = (int*)malloc(10000sizeof(int));
    fstr_int = (int
    )malloc(10000sizeof(int));
    countc = (int
    )malloc(10000sizeof(int));
    printf("请输入文件名以及存储路径:");
    scanf("%s", address);//读入文件名以及存储路径
    if ((pf = fopen(address, "w")) == NULL)//在存储路径新建文件
    {
    perror("fopen");//如果新建失败,报错
    return 1;//主函数返回异常值1
    }
    printf("请输入student number:");//依次读取个人信息
    scanf("%s", a.stn);
    printf("请输入first name:");
    scanf("%s", a.fn);
    printf("请输入last name:");
    scanf("%s", a.ln);
    printf("请输入gender:");
    scanf("%s", a.gen);
    printf("请输入major:");
    scanf("%s", a.maj);
    printf("请输入address of dormitory:");
    scanf("%s", a.aod);
    printf("是否有names of roommates?\n");//是否有names of roommates
    printf("在此键入1或0(1:有 0:没有):");
    scanf("%d", &charge);
    if (charge)
    {
    printf("请输入names of roommates:");//有则输入names of roommates
    scanf("%s", a.nor);
    }
    else { a.nor[0] = 'N'; a.nor[1] = 'o'; a.nor[2] = 'n'; a.nor[3] = 'e'; }//没有则为None
    fprintf(pf, "student number:%s\nfirst name:%s\nlast name:%s\ngender:%s\nmajor:%s\naddress of dormitory:%s\nnames of roommates:%s\n", a.stn, a.fn, a.ln, a.gen, a.maj, a.aod, a.nor);
    //将个人信息输入到文件中
    printf("请输入需要加密的自我介绍:\n");
    getchar();//读取回车
    gets(str);//读取自我介绍原文(明文)
    printf("加密方程为:f(x)=a
    xx+b\n");
    printf("请输入加密参数a和b:");
    scanf("%d%d" ,& a1, &b1);//读入加密参数
    encrypt(str,str_int,a1,b1,&size,countc);//加密自我介绍明文,并将加密后的密文的字符的ascll码返回str_int
    printf("自我介绍加密成功\n");
    length=ftell(pf);//记录自我介绍前(即个人信息后)的指针位置,方便第二次读取自我介绍
    fclose(pf);//关闭文件,换一种打开方式(二进制)
    if ((pf = fopen(address, "ab")) == NULL)//以二进制末尾追加打开文件
    {
    perror("fopen");//如果打开失败,报错
    return 1;//主函数返回异常值1
    }
    printf("正在写入加密内容...\n");
    fwrite(str_int, sizeof(int), size, pf);//将加密后的密文写入文件(二进制写入)
    printf("加密内容写入完成\n");
    printf("文件关闭中...\n");
    fclose(pf);//关闭文件
    printf("文件关闭成功\n\n");
    printf("正在打开文件...\n");
    if ((pf = fopen(address, "rb")) == NULL)//再次打开文件,二进制只读
    {
    perror("fopen");//打开失败则报错
    return 1;
    }
    fseek(pf, length, SEEK_SET);//将指针移到自我介绍前(即个人信息后)的指针位置,准备进行读取下面的自我介绍密文
    fread(fstr_int, sizeof(int), size, pf);//读取自我介绍密文,密文存储到fstr_int(二进制读取)
    printf("正在解密自我介绍...\n");
    decrypt(fstr, fstr_int,a1, b1, size,countc);//解密密文,将明文存储到fstr
    printf("解密成功:\n%s\n",fstr);//打印自我介绍明文
    fclose(pf);//关闭文件
    pf = NULL;
    printf("文件关闭成功\n");
    free(str);//释放内存
    free(fstr);
    free(str_int);
    free(fstr_int);
    free(countc);
    return 0;
    }
    void encrypt(char
    p1, int* p2, int a,int b,intsize,intcountc)
    //加密函数 char* p1加密前的字符串 int* p2加密后的字符串的ascll码 a,b加密方程的参数 (int* size)p2的元素个数,int* countc 记录汉字出现的位置
    {
    int x,count=0;//x 当前位置对应的明文字符 count 记录字符串字符个数
    char* p = p1;//加密前的字符串
    int* q = p2;//加密后的字符串的ascll码
    while (*p != '\0')
    {
    x = p;//读入当前位置对应的明文字符
    q = a * x * x + b;//按照加密方程加密ascll码,并存储到q
    if (x < 0)
    (countc + count) = 1; else *(countc + count) = 0;//如果该位置是汉字,则countc记录为1,否则为0
    p++;//指针指向下一位
    q++;
    count++;//字符个数++
    }
    *size = count;//存储字符个数到size
    }

    void decrypt(char* p1,intp2, int a, int b,int size, int countc)
    //解密函数 char* p1解密后的字符串 int* p2解密前的字符串的ascll码 a,b加密方程的参数 (int* size)p2的元素个数,int* countc 记录汉字出现的位置
    {
    int x,count=0;//x当前位置对应的密文字符的ascll码 count记录当前位置
    char* p = p1;//解密后的字符串
    int* q = p2;//加密后的字符串的ascll码
    while (count<size)//如果位置没到最后
    {
    x = *q;//读入当前位置对应的密文字符的ascll码
    p = sqrt((x - b) / a);//解密ascll码
    if (
    (countc + count))*p = -*p;//如果该位置为汉字,则ascll码取负
    p++;//指针指向下一位
    q++;
    count++; //当前位置向前
    }
    *p = '\0';//
    }
    试一下这个

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(3条)

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 6月8日
  • 已采纳回答 6月8日
  • 修改了问题 6月6日
  • 赞助了问题酬金5元 6月6日
  • 展开全部

悬赏问题

  • ¥15 关于#极限编程#的问题,请各位专家解答!
  • ¥20 win11账户锁定时间设为0无法登录
  • ¥45 C#学生成绩管理系统
  • ¥15 VB.NET2022如何生成发布成exe文件
  • ¥30 matlab appdesigner私有函数嵌套整合
  • ¥15 vb6.0使用jmail接收smtp邮件并另存附件到D盘
  • ¥30 vb net 使用 sendMessage 如何输入鼠标坐标
  • ¥15 关于freesurfer使用freeview可视化的问题
  • ¥100 谁能在荣耀自带系统MagicOS版本下,隐藏手机桌面图标?
  • ¥15 求SC-LIWC词典!