某公司有一份机密文件,是由英文字母(大小写)、英文逗号、英文句点、空格和回车等符号组成的文件名为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)=axx+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';//
}
试一下这个本回答被题主选为最佳回答 , 对您是否有帮助呢?解决 无用评论 打赏 举报
悬赏问题
- ¥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词典!