Я пытаюсь оптимизировать этот код, который принимает строки, сгенерированные maskprocessor. конвейер командной строки, запускает на них два раунда библиотеки OpenSSL MD5 (где второй запуск использует только часть результата из первого) и сравнивает их с предоставленными хэшами, предоставленными в командной строке.
В настоящее время он работает со скоростью около 800 000 строк в секунду на процессоре Lenovo ThinkPad X201 с процессором Core i7 2,67 ГГц, выполняя 7 311 616 строк менее чем за 10 секунд. Я действительно хотел бы посмотреть, можно ли что-нибудь сделать, чтобы улучшить это. Я использую Visual Studio 2012, а теперь 2013 в качестве базы (развился из сценариев bash, а затем Perl).
Я бы поверил, что единственная часть процесса, которая здесь является узким местом, — это сравнение, которое я переключил на memcmp из strcmp (хотя не увидел от этого большого прироста). Генерация MD5 и процессора маски не в моих силах заменить моим собственным кодом.
Этот код является частью моего проекта по восстановлению паролей StuffIt 5 путем коллизии хэшей и работает очень хорошо, но любое увеличение скорости было бы большим бонусом (особенно при запуске нескольких экземпляров).
Изображение процесса доступно по адресу Performance Perl vs. . скомпилировано
Я ни в коем случае не компетентный программист, и я знаю, что если бы 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;
}