Какие оптимизации можно сделать для этого пользовательского сравнения MD5?

Я пытаюсь оптимизировать этот код, который принимает строки, сгенерированные maskprocessor будучи загруженным по каналу командной строки, запускает на них два раунда библиотеки Open5L MD5 (где второй прогон использует только частичную часть результата первого) и сравнивает их с предоставленными хэшами, предоставленными в командной строке.

В настоящее время он работает со скоростью примерно 800 000 строк в секунду на процессоре Lenovo ThinkPad X201 с частотой 2,67 ГГц Core i7, выполняя 7 311 616 строк за 10 секунд. Мне бы очень хотелось посмотреть, есть ли что-нибудь, что можно сделать, чтобы улучшить это. Я использую Visual Studio 2012, а теперь и 2013 год в качестве своей базы (эволюционировал из bash, а затем из сценариев Perl).

Я полагаю, что единственная часть процесса, которая является здесь узким местом, — это сравнение, которое я переключил на memcmp из strcmp (хотя и не увидел большого прироста от этого). Генерация MD5 и маскпроцессора не поддается моей замене собственным кодом.

Этот код является частью моего проекта по восстановлению паролей StuffIt 5 путем коллизий хешей, и работает очень хорошо, но любое увеличение скорости будет большим бонусом (особенно при запуске нескольких экземпляров).

Изображение процесса доступно на Производительность Perl против скомпилированного

Я ни в коем случае не являюсь компетентным программистом, и я знаю, что если Hashcat или какой-либо из взломщиков паролей, ускоренных с помощью графического процессора, смогут реализовать этот алгоритм, то он вылетит из воды, но для его реализации недостаточно требований. Поверь мне, я спросил 🙁

    #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

Решение

Вы можете получить улучшение, устраняя петли вокруг 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]);
0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]