您的位置:首页 > 其它

多线程程序设计------一个实例(SDES破解)

2012-03-26 22:18 316 查看
#include"time.h"
#include"stdlib.h"
#include"stdio.h"
#include"S_DES.h"
#include"string.h"
#include"windows.h"
#include"iostream.h"

#define STRMAX 50
const WM_GET_MSG=WM_USER+1;//搜索成功的消息类型
const WM_FINISH_MSG=WM_USER+2;//搜索完毕的消息类型
DWORD MainThreadID;//主线程ID

typedef struct threadstruct//线程参数结构体
{
int ID;
int start;
int end;
char cipher[STRMAX];
}threadstruct;

int WriteToFile(char *filename,char *char_str,int str_len)//将密文写入文件
{
int FileLength;
FILE *SecretFile=fopen(filename,"w");
if(SecretFile==NULL)
{
printf("文件打开失败!\n");
return -1;
}
FileLength=fwrite(char_str,sizeof(char),str_len,SecretFile);
if(FileLength<1)
{
printf("写入文件失败!\n");
return FileLength;
}
fclose(SecretFile);
return 1;
}

int ReadFromFile(char *filename,char *char_str,int *str_len)//从文件读取密文
{
int FileLength;
FILE *SecretFile=fopen(filename,"r");
if(SecretFile==NULL)
{
printf("文件打开失败!\n");
return -1;
}
FileLength=fread(char_str,sizeof(char),STRMAX,SecretFile);
if(FileLength<1)
{
printf("读取文件失败!\n");
return FileLength;
}
*str_len=FileLength;
fclose(SecretFile);
return 1;
}

DWORD WINAPI SerchFunc(LPVOID lpData)//线程执行函数
{
int *return_number=new int;
int i,ID,start,end;
char cipher[STRMAX],output[STRMAX];
start=((threadstruct *)lpData)->start;
end=((threadstruct *)lpData)->end;
ID=((threadstruct *)lpData)->ID;
strcpy(cipher,((threadstruct *)lpData)->cipher);
for(i=start;i<end;i++)
{
SDES A(i);
A.StringInvCipher((BYTE *)cipher,strlen(cipher),(BYTE *)output);//字符串解密
if(!strcmp(output,"this is a secret!"))
{
*return_number=i;
PostThreadMessage(MainThreadID,WM_GET_MSG,0,(LPARAM)return_number);//找到所需密钥,此处需要传指针类型,如果直接传变量地址就会出错
//PostThreadMessage(MainThreadID,WM_GET_MSG,0,(LPARAM)&i);
return 1;
}
}
*return_number=ID;
PostThreadMessage(MainThreadID,WM_FINISH_MSG,0,(LPARAM)return_number);//搜索完毕
return 0;
}

int BruteForce(int ThreadCount,char *cipherstr)//暴力破解函数
{
int i;
int by;
char output[STRMAX];
BYTE to[10];
HANDLE hThread[STRMAX];
threadstruct ts[STRMAX];
by=1024/ThreadCount;
for(i=0;i<ThreadCount;i++)
{
ts[i].start=by*i;//分派搜索字段
ts[i].end=by*(i+1);
ts[i].ID=i;
strcpy(ts[i].cipher,cipherstr);
hThread[i] = CreateThread(NULL,0,SerchFunc,(LPVOID)&ts[i],0,NULL);//启动新的线程
CloseHandle(hThread[i]);
}
return 0;
}

int DealMessage(MSG &msg)
{
int i;
if(msg.message== WM_GET_MSG)//收到子线程的成功消息
{
i=*((int *)msg.lParam);
return i;
}
else if(msg.message== WM_FINISH_MSG)
return -1;
else
return -2;
}

int main()
{
MSG msg;
double duration;
int key,filelen,FinishCount,ThreadCount,flag;
char ch,str[STRMAX],strout[STRMAX];
clock_t start, finish;
srand((unsigned)time(NULL));
cout<<"----------------------------------------"<<endl;
cout<<"            选择功能"<<endl;
cout<<"\n   1.加密            2.解密\n";
cout<<"----------------------------------------"<<endl;
cin>>ch;
cout<<"----------------------------------------"<<endl;
if(ch=='1')
{
cin.get();
cout<<"输入一段明文进行加密(50个字符以内):\n";
cin.getline(str,STRMAX);
cout<<"----------------------------------------"<<endl;
key=rand()%1024;
//key=1000;
cout<<(int)key<<endl;
cout<<"开始加密。。。。。。"<<endl;
SDES A(key);
A.StringCipher((BYTE *)str,strlen(str),(BYTE *)strout);
if(WriteToFile("cipher.dat",strout,strlen(str))<1)
{
cout<<"密文写入错误!"<<endl;
return 0;
}
cout<<"加密完成,密文存于cipher.dat文件中"<<endl;
cout<<"----------------------------------------"<<endl;
getchar();
}
else if(ch=='2')
{
cout<<"输入要启动的线程个数(2的幂1,2,4...):";
cin>>ThreadCount;
ReadFromFile("cipher.dat",str,&filelen);
str[filelen]='\0';
cout<<"----------------------------------------"<<endl;
cout<<"开始暴力破解。。。。。。"<<endl;
MainThreadID=GetCurrentThreadId();
BruteForce(ThreadCount,str);
start = clock();
FinishCount=0;
while(1)
{
if(GetMessage(&msg,NULL,0,0))//主线程循环捕获消息
//if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
flag=DealMessage(msg);
if(flag==-1)//收到子线程的成功消息
{
FinishCount++;
if(FinishCount==ThreadCount)
{
cout<<"所有线程搜索完毕没有找到密钥!这TM不可能啊"<<endl;
break;
}
}
else if(flag==-2)//搜索完毕的消息
{
cout<<"消息传递出错!"<<endl;
break;
}
else
{
cout<<"找到密钥"<<flag<<endl;
break;
}
}
}
finish = clock();
duration = (double)(finish - start) / CLOCKS_PER_SEC; //计算耗时
cout<<"----------------------------------------"<<endl;
cout<<"\n   -------->耗时"<<duration<<"秒<----------\n"<<endl;
getchar();
}
else
cout<<"输入1或者2\n";
return 1;
}

一些知识点

1.主线程创建新的线程来穷举破译SDES的密钥

2.新线程利用PostThreadMessage与主线程进行通信

3.主线程向新线程传递结构体参数

4.主线程对MSG类型的消息的处理

运行截图



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: