?? 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 + -