📄 pass.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 + -