MD5ハッシュからパスワードを回復するというタスクがあります。 パスワードは単純で、7桁で構成され、8桁で始まります。 私はすぐに予約をします-私のパスワード、私はそれを陳腐に忘れました、そしてこれは他人のパスワードを総当たり攻撃する方法についての指示ではありません。
プログラムは、可能な限り迅速に結果を得るために、いくつかのスレッドで動作する必要があります。 デュアルコアプロセッサを搭載したコンピューターで実行するためだけに。 1つのスレッドで両方のコアを最大化することはできません。
2つの方法を検討してください:複数のワークフローを作成する、およびOpenMPを使用する
最初の方法は、複数のスレッドを作成することです。
簡単にするために、結果を出力するときにフローを同期せずに、問題を正面から解決します。 それ以外の場合は、デッドロック、またはむしろそれらの不在に注意する必要があります。
//
const int g_nNumberOfThreads = 4;
const int g_nFrom = 8000000;
const int g_nTo = 8999999;
const string g_strCompareWith = "4ac7b1796b90478f2991bb9a7b05d2bf" ;
time_t g_timeElapsed;
// ,
struct THREAD_PARAMS
{
int nFrom;
int nTo;
};
// MD5
BOOL GetMD5Hash( string strIn, string &strHash)
//
DWORD WINAPI _WorkerThread(LPVOID pParams)
{
//
THREAD_PARAMS *pThreadParams = (THREAD_PARAMS*)pParams;
int nFrom = pThreadParams->nFrom;
int nTo = pThreadParams->nTo;
delete pParams;
string strHash;
for ( int i = nFrom; i < nTo; ++i)
{
stringstream stream;
stream << i;
//
GetMD5Hash(stream.str(), strHash);
//
if (strHash == g_strCompareWith)
{
//
cout << "Password is: " << stream.str() << endl;
cout << "Elapsed time: " << time(NULL) - g_timeElapsed << " sec." << endl;
exit(0);
}
// 10000
if ((i % 10000) == 0)
{
cout << "Current password: " << i << " Elapsed time: " << time(NULL) - g_timeElapsed << " sec." << endl;
}
}
return 0;
}
//
void MultiThreadWay()
{
int nDataLength = ( int )(g_nTo - g_nFrom) / g_nNumberOfThreads;
HANDLE *hThreads = new HANDLE[g_nNumberOfThreads];
for ( int i = 0; i < g_nNumberOfThreads; ++i)
{
THREAD_PARAMS *pParams = new THREAD_PARAMS();
pParams->nFrom = g_nFrom + (i * nDataLength);
pParams->nTo = pParams->nFrom + nDataLength;
hThreads[i] = CreateThread(NULL, 0, _WorkerThread, pParams, 0, NULL);
Sleep(100);
}
WaitForMultipleObjects(g_nNumberOfThreads, hThreads, TRUE, INFINITE);
delete [] hThreads;
}
//
int _tmain( int argc, _TCHAR* argv[])
{
g_timeElapsed = time(NULL);
MultiThreadWay();
return 0;
}
*このソースコードは、 ソースコードハイライターで強調表示されました。
方法2-OpenMPを使用する
ヘッダーファイルを含める必要があります
#include <omp.h>/ openmpコンパイラオプションを追加します。 Visual Studioでは、これはプロジェクトプロパティを介して行われます。
//
const int g_nNumberOfThreads = 4;
const int g_nFrom = 8000000;
const int g_nTo = 8999999;
const string g_strCompareWith = "4ac7b1796b90478f2991bb9a7b05d2bf" ;
time_t g_timeElapsed;
// MD5
BOOL GetMD5Hash( string strIn, string &strHash)
int _tmain( int argc, _TCHAR* argv[])
{
g_timeElapsed = time(NULL);
//
omp_set_num_threads(g_nNumberOfThreads);
// , .
// g_nNumberOfThreads .
// .
#pragma omp parallel for
for ( int i = g_nFrom; i < g_nTo; ++i)
{
//
//
string strHash;
stringstream stream;
stream << i;
//
GetMD5Hash(stream.str(), strHash);
//
if (strHash == g_strCompareWith)
{
cout << "Password is: " << stream.str() << endl;
cout << "Elapsed time: " << time(NULL) - g_timeElapsed << " sec." << endl;
exit(0);
}
// 10000
if ((i % 10000) == 0)
{
// .
// , ""
#pragma omp critical
{
cout << "Current password: " << i << " Elapsed time: " << time(NULL) - g_timeElapsed << " sec." << endl;
}
}
}
return 0;
}
*このソースコードは、 ソースコードハイライターで強調表示されました。
OpenMPを使用すると、コードははるかに短くなります。 この場合、私のコンピューターでの2番目の方法によるパスワードの計算ははるかに高速でした。 両方の方法が両方のコアをほぼ完全に「ロード」したという事実にもかかわらず。
OpenMPに興味がある場合は、IntelのWebサイトに投稿された記事を参照してください。
OpenMPの使用開始OpenMPを使用したスレッド間の効率的な負荷分散高度なOpenMPプログラミングまた、
OpenMP Webサイトにアクセスすることを忘れないでください。 そこで、OpenMPおよび
OpenMP仕様をサポートする
コンパイラのリストを見つけることができます。