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

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

运行截图


发布了24 篇原创文章 · 获赞 18 · 访问量 31万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章