用ascll码法对文本/二进制文件进行加密解密【注释详细】

题目

步骤一:创建一个文本/二进制文件。实现:1)文件名以及存储路径由用户输入;2)正文内容为英文,由用户输入,包括student number, first name, last name, gender, major, address of dormitory, names of roommates (if has)。

步骤二:在上述已创建的文本文件中追加一段加密内容。实现:1)采用加密方程式进行加密,其中a、b的值自定义;2)正文内容由用户输入,内容为中文/英文,字数大于等于20。

步骤三:打开上述文本/二进制文件,解密文件并明文显示文件中的内容。

解题思路

先由用户输入信息,并将信息用文件操作函数输出到用户指定的文件中,再将用户输入的待加密的明文用二进制文件操作函数进行加密并输出到文件,最后打开文件并解密加密的内容,将明文打印到屏幕。其中需要注意三个点:

1.在步骤二用二进制文件操作法之前需要先将文件关闭,再使用二进制打开参数打开文件。因为步骤一是使用的是文本文件打开参数,操作二进制文件必须用二进制打开参数,不加这一步编译器不会报错,但是会出奇怪的bug,有的数据存储读取会有问题,可能会产生的bug请见另一篇博客:https://blog.csdn.net/Henyry/article/details/122161831

2.对于汉字:因为汉字的ascll码是两个负数,所以需要进行特殊判断特殊处理,在解密汉字的时候因为加密方程将x平方了,而解密开方的时候都是正数,所以需要特殊记录汉字的位置,在解密的时候加上负号。

3.关于解密:因为char类型的范围是-128 ~ 127,所以在加密之后的解密过程中就无法得到原ascll码(如果加密运算只是加减就可以),所以本文采用笨办法,再新建一个int数组(用指针加分配地址实现)存储ascll码加密后的值用于解密。

//为了在一个程序内同时演示文本文件和二进制文件操作,本代码对步骤一采用文本文件操作法,对步骤二采用二进制文件操作法。

完整代码

#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(10000*sizeof(int));
	fstr_int = (int*)malloc(10000*sizeof(int));
	countc = (int*)malloc(10000*sizeof(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*x*x+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,int*size,int*countc)
//加密函数 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,int*p2, 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';//给字符串补上结束符
}

运行截图

 

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值