#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类型的消息的处理
运行截图