⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pass.c

📁 这是能将文件进行加密的一个工具
💻 C
字号:
///////////////////////////////////////////////////////////////////////////////
//
//  文	件: FilePass.h
//		加密函数相关
//
//  作  者: 江南孤峰 
//  联  系:QQ: 403324669   
//  时  间: 2007--3--3
//
///////////////////////////////////////////////////////////////////////////////

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <process.h>
#include <conio.h>
#include <ctype.h>
#include <io.h>
#include "FilePass.h"

// 加密文件的算法(更新算法只要更新该函数即可)
void	AddPass(FILE *fpDest,FILE *fpSource,int passKey){
	char	c;
	long	temp = 0;

	srand(passKey);
	temp = rand();
	if(passKey + temp + 256 < 0)
		temp = passKey % 100;
	fprintf(fpDest," %ld",temp^passKey);
	while(fscanf(fpSource,"%c",&c) != EOF) // 加密后存入目标文件
		fprintf(fpDest," %ld",c + passKey - temp);
}

// 解密文件
void	FreePass(FILE *fpDest,FILE *fpSource,int passKey){
	long temp = 0;
	long tempSource = 0;

	fscanf(fpSource," %ld",&temp);
	tempSource = temp^passKey;
	while(fscanf(fpSource," %ld",&temp) != EOF)
		fprintf(fpDest,"%c",temp + tempSource - passKey);
}

// 加密文件
int	AddPassForFile(
		   char *strFileName,		// 待加密文件的文件名
		   char *strAddFileSuffix,	// 加密器中指定的待加密文件后缀
		   char *strFreeFileSuffix,	// 加密后文件后缀
		   char *strPass,		// 用户输入的密码
		   char *strDES			// 密码对应的 DES 密文
	){
	FILE	*fpSourceFile;
	FILE	*fpDestFile;
	char	strDestFileName[FILE_LENGTH+2];
	int	passKey = 0;

	if(CheckFileExistRead(strFileName) == FAILED)
		return FAILED;	
	if(IsFileSuffixValid(strFileName,strAddFileSuffix) == FALSE){
		printf("文件类型与加密器中定义的不同 !\n");
		return FAILED;
	}	
	if((fpSourceFile = fopen(strFileName,"r")) == NULL){
		printf("文件 %s 打开失败\n",strFileName);
		return FAILED;
	}
	printf("尝试对文件 %s 加密\n",strFileName);
	GetDestFileName(			// 根据原文件获取加密后的文件名
		strDestFileName,
		strFileName,
		strFreeFileSuffix,
		strAddFileSuffix
	);
	if((fpDestFile = fopen(strDestFileName,"w+")) == NULL){
		printf("文件 %s 创建失败\n",strDestFileName);
		fclose(fpSourceFile);
		return FAILED;
	}
	printf("文件 %s 创建完成\n",strDestFileName);
	fprintf(fpDestFile,"%s ",strDES);	
	fprintf(fpDestFile,"%s",strAddFileSuffix); 
	printf("文件 %s 加密中……\n",strFileName);
	passKey = GetPassKey(strDES,strPass);	// 根据密文获取加密因子
	AddPass(fpDestFile,fpSourceFile,passKey);
	fclose(fpDestFile);
	fclose(fpSourceFile);
	return SUCCESS;
}

// 解密文件
int	FreePassForFile(
		char *strFileName,
		char *strFreeFileSuffix,
		char *strPass,
		char *strDES
	){
	FILE	*fpSourceFile;
	FILE	*fpDestFile;
	char	strDestFileName[FILE_LENGTH+2] = {""};
	char	strDestFileSuffix[FILE_LENGTH+2] = {""};
	char	strTempDES[DES_LENGTH+2] = {""};
	int	passKey = 0;
	int	i = 0;

	if(CheckFileExistRead(strFileName) == FAILED)
		return FAILED;
	if(IsFileSuffixValid(strFileName,strFreeFileSuffix) == FALSE){
		printf("文件类型与加密器中定义的不符\n");
		return FAILED;
	}
	if((fpSourceFile = fopen(strFileName,"r")) == NULL){
		printf("文件 %s 打开失败\n",strFileName);
		return FAILED;
	}
	printf("尝试对文件 %s 解密\n",strFileName);
	for(i = 0; !feof(fpSourceFile) && i < DES_LENGTH; i ++)	
		strTempDES[i] = fgetc(fpSourceFile);
	strTempDES[i] = '\0';
	if(strcmp(strTempDES,strDES)){ 
		printf("密码错误 !\n");
		return FAILED;
	}
	fscanf(fpSourceFile," %s",strDestFileSuffix);
	GetDestFileName(
		strDestFileName,
		strFileName,
		strDestFileSuffix,
		strFreeFileSuffix
	);
	if((fpDestFile = fopen(strDestFileName,"w+")) == NULL){
		printf("文件 %s 创建失败\n",strDestFileName);
		fclose(fpSourceFile);
		return FAILED;
	}
	printf("文件 %s 创建完成\n",strDestFileName);
	printf("文件 %s 解密中……\n",strFileName);
	passKey = GetPassKey(strPass,strDES); 
	FreePass(fpDestFile,fpSourceFile,passKey);
	fclose(fpDestFile);
	fclose(fpSourceFile);
	return SUCCESS;
}

// 测试文件是否可读是否存在
int	CheckFileExistRead(char *strFileName){
	if(_access(strFileName,0) == -1){	// 文件是否存在
		printf("文件 %s 不存在\n",strFileName);
		return FAILED;
	}
	if(_access(strFileName,4) == -1){	// 文件是否可读
		printf("文件 %s 不可读\n",strFileName);
		return FAILED;
	}
	return SUCCESS;
}

// 输入密码
int GetUserInputPass(char *strSavePass){
	char c = 's';
	int  i = 0;

 	while((i<PASS_LENGTH + 2)&&(c!='\r')){
		c = (char)getch();		// 无回显输入
	    	if(c == BKSPACE){		// 删除键
	      		if(i > 0){
				strSavePass[--i]= '\0';
		  		printf("\b \b");		
		  	}
		      	else 	
				putchar(BELL); 	// 响铃
			continue;
	       	}
	 	else if(c != '\r' && !iscntrl(c)){
		 	strSavePass[i ++] = c; 	// 只要不是退格回车和控制字符就接受
	   		putchar('*'); 		// 回显星号
	 	}
	      	else if(c == ENTER){		// 回车表示输入完毕
	    		strSavePass[i] = '\0';
			break;
		}
	}
	if(i < PASS_LENGTH_MIN || i > PASS_LENGTH){
		printf("\n错误:密码长度不在[%d,%d]范围内 !\n",PASS_LENGTH_MIN,PASS_LENGTH);
		return FAILED;
	}
	printf("\n");
	return SUCCESS;
}

// 用于快速排序的比较函数
int	MyCompare(const char *i,const char *j){
	if(*i > *j)
		return 1;
	if(*i < *j)
		return -1;
	return 0;
} 

// 将密码变为DES密文
void ChangePassToDES(char *strPass){
	char s[]="A1aB2bC3cD4dE5eF6fG7gH8hI9iJ0jK0kL1lM2mN3nO4oP5pQ6qR7rS8sT9tUuVvWwXxYyZz";
	char strTempDES[DES_LENGTH+2];
	int  i,j,n;
	
	j=strlen(strPass);
	for(i=0; i < j; i ++)
		strPass[i] = s[strPass[i] % 72]; // 替换		
	while(strlen(strPass) != DES_LENGTH){
		strcpy(strTempDES,strPass);
		qsort((char*)strTempDES,strlen(strTempDES),sizeof(char),MyCompare);// 排序
		n = strlen(strTempDES);	
		j = strlen(strPass);
		for(i = 0; i < n && j < DES_LENGTH; j ++,i ++)
			strPass[j] = s[strTempDES[i] % 72]; 
		strPass[j] = '\0';
		if(j == DES_LENGTH)
			break;
	}
}

// 获取DES密文
int	GetFilePassDES(char *strPass,char *strDES,int iOperate){
	printf("请输入长度在%d-%d之间的密码:",PASS_LENGTH_MIN,PASS_LENGTH);
	if(GetUserInputPass(strPass) == SUCCESS){
		if(iOperate == ADD_PASS)
			printf("请牢记本次加密的密码:%s\n",strPass);
		strcpy(strDES,strPass);
		ChangePassToDES(strDES);
		return SUCCESS;
	}
	return FAILED;

}

// 根据密文strDES和密码strPass求加密因子
int GetPassKey(char *strDES,char *strPass){
	size_t i = 0;
	int key = 0;
	int keyAdd = 0; 

	for(i = 0; i < strlen(strDES); i ++)
		key += strDES[i];
	for(i = 0; i < strlen(strPass); i ++)
		keyAdd += strPass[i];
	return key + keyAdd;
}

// 根据原文件名获取加密或者解密后的文件名,也就是改变后缀
int GetDestFileName(
		char *strDestFileName,		
		char *strSourceFileName,
		char *strDestFileSuffix,
		char *strSourceFileSuffix
		){
	char	*p,*pSuffix;

	strcpy(strDestFileName,strSourceFileName);
	pSuffix = p = strstr(strDestFileName,strSourceFileSuffix);
	while(p != NULL){		// 也许有重复的后缀串
		pSuffix = p;
		p++;
		p = strstr(p,strSourceFileSuffix);
	}
	if(pSuffix == NULL){
		printf("文件 %s 后缀名替换失败\n",strSourceFileName);
		return FAILED;
	}
	else
		strcpy(pSuffix,strDestFileSuffix);
	return SUCCESS;
}

// 获取用户的字符串输入 其中_cgets()函数是非标准C函数
int GetUserInputFileName(char *strFileName){
	char	*pStr;
	char	buffer[FILE_LENGTH+10] = { FILE_LENGTH + 4 };

	pStr = _cgets(buffer);
	strcpy(strFileName,pStr);
	if(strlen(strFileName) > FILE_LENGTH || !strlen(strFileName)){
		printf("%s%d%s\n","错误: 文件名的长度不在[1,",FILE_LENGTH,"]范围内 !\n");
		return FAILED;
	}
	return SUCCESS;
}

// 检查文件后缀名是否有效
int	IsFileSuffixValid(char *strFileName,char *strSuffix){
	int i = strlen(strFileName) - 1;
	int j = strlen(strSuffix) - 1;
	int iFlagSuccess = TRUE;

	for(; i >= 0 && j >= 0; i --,j --){
		if(strSuffix[j] != strFileName[i]){
			iFlagSuccess = FALSE;
			break;
		}
	}
	if(j >= 0 || iFlagSuccess == FALSE)
		iFlagSuccess = FALSE;
	return iFlagSuccess;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -