我正在尝试优化此代码,该代码将maskprocessor生成的字符串通过命令行管道提供,在它们上运行两轮OpenSSL libary MD5(其中第二次运行仅使用部分数量的来自第一个的结果)并将它们与命令行上提供的散列进行比较。
目前在Core i7 2.67GHz联想ThinkPad X201上以大约800,000线/秒的速度运行,在10秒内完成7,311,616线。我真的很想看看是否有任何可以改进的方法。我使用Visual Studio 2012,现在使用2013作为我的基础(从bash演变而来是Perl脚本)。
我认为这个过程中唯一的瓶颈就是比较,我已经从strcmp切换到了memcmp(虽然没有看到大的提升)。 MD5和掩码处理器的生成超出了我用自己的代码替换的能力。
此代码是我通过哈希冲突恢复StuffIt 5密码的项目的一部分,并且运行得非常好,但速度的提升将是一个很大的好处(特别是在运行多个实例时)。
提供了该流程的图片我绝不是一个称职的程序员,而且我知道如果Hashcat或任何GPU加速密码破解程序都可以实现这个算法,它会让我失去水力,但是没有足够的需求来实现它。相信我,我问:(
#define _CRT_SECURE_NO_WARNINGS
// Need OpenSSL Libs linked, headers linked, dlls linked
#include <stdio.h>
#include <string.h>
#include <openssl/md5.h>
#include <iostream>
#include <ctime>
using namespace std;
int main(int argc, char* argv[])
{
/* Start - Setup Timer */
std::clock_t start;
double duration;
start = std::clock();
/* End - Setup Timer */
/* Start - Hash Length Check */
int j;
for(int i = 1; i < argc; i++) {
j = strlen(argv[i]);
if (j != 10){
std::cout<<argv[i]<<" is "<<j<<" characters long - not 10! Quitting\n";
return 0;}
}
/* End - Hash Length Check */
/* Start - Line Entry and Count */
char string[40];
int i;
__int64 linecount = 0; // caps at 9,223,372,036,854,775,807
int millioncount = 0;
// printf("Enter a string: ");
while(fgets(string, 40, stdin)){
/* remove newline, if present */
i = strlen(string)-1;
if( string[i] == '\n')
string[i] = '\0';
//printf("This is your string: %s", string);
linecount++;
if(linecount%10000000 == 0){
millioncount++;
duration = ( std::clock() - start ) / (double) CLOCKS_PER_SEC;
double linespersec = linecount/duration;
std::cout<<millioncount*10<<" million tries ("<<linespersec<<" l/s)\n";
}
/* End- Line Entry */
/* Start - MD5 Round 1 */
unsigned char digest[MD5_DIGEST_LENGTH];
char string2[5];
MD5((unsigned char*)&string, strlen(string), (unsigned char*)&digest);
/* End - MD5 Round 1 */
/* Start - MD5 Round 2 */
// Set the string to the second MD5 hash of the first 5 characters (10 bit)
//for(int i = 0; i < 5; i++)
//string2[i] = digest[i];
memcpy(string2, digest, 5);
MD5((unsigned char*)&string2, 5, (unsigned char*)&digest);
char mdString3[33];
for(int i = 0; i < 5; i++)
sprintf(&mdString3[i*2], "%02x", (unsigned int)digest[i]);
// printf("\nmd5 digest: %s\n", mdString3);
/* End - MD5 Round 2 */
/* Start - Hash Check */
for(int i = 1; i < argc; i++) {
//if (mdString3[0] == argv[i][0] && strcmp(mdString3, argv[i]) == 0){ // added the 0 comp, no real improvements
if (memcmp(mdString3, argv[i], 10) == 0){ // 785-795k
printf("Success at: %s", string);
duration = ( std::clock() - start ) / (double) CLOCKS_PER_SEC;
double linespersec = linecount/duration;
std::cout<<" for "<< argv[i]<<" in "<< duration <<" seconds at line "<<linecount<<" ("<<linespersec<<" l/s)\n";
}
}
}
/* End - Hash Check*/
/* Start - Timer Closeout */
duration = ( std::clock() - start ) / (double) CLOCKS_PER_SEC;
double linespersec = linecount/duration;
std::cout<<"Exhausted search of "<<linecount<<" lines in "<< duration <<" seconds ("<<linespersec<<" l/s)\n";
/* End - Timer Closeout */
return 0;
}
答案 0 :(得分:0)
您可以通过消除sprintf
调用周围的循环来获得改进,并改为使用它:
sprintf(&mdString3[0],
"%02x%02x%02x%02x%02x",
(unsigned char)digest[0],
(unsigned char)digest[1],
(unsigned char)digest[2],
(unsigned char)digest[3],
(unsigned char)digest[4]);