多線程程序設計------一個實例(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萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章