6桁の数字という前提でMD5のダイジェスト値から数字を逆算するやつ。
こちら
http://qiita.com/nmatsui/items/8a33941072668f3ac55b
のを少し修正して65ms位になりました。
findmd5.c
#include <stdio.h>
#include <string.h>
#include <libiomp/omp.h>
#include <openssl/md5.h>
#define MD5_DIGEST_LENGTH 16
void decode(unsigned char* out, const char* in) {
for (int i = 0; i < MD5_DIGEST_LENGTH; i++)
sscanf(&in[i*2], "%02x", &out[i]);
}
void md5(unsigned char* buf, const char* in, int len) {
MD5_CTX ctx;
MD5_Init(&ctx);
MD5_Update(&ctx, in, len);
MD5_Final(buf, &ctx);
}
int main(int argc, char* argv[]) {
if (argc != 3) return 1;
const char* SALT = argv[1];
unsigned char digest[MD5_DIGEST_LENGTH];
decode(digest, argv[2]);
int found = 0;
#pragma omp parallel for
for (int i = 0; i < 1000000; i++) {
if (found) continue;
char origin[256];
unsigned char hash[MD5_DIGEST_LENGTH];
snprintf(origin, sizeof(origin), "%s$%06d", SALT, i);
md5(hash, origin, strlen(origin));
if (strncmp(digest, hash, MD5_DIGEST_LENGTH) == 0) {
printf("match[%06d]\n", i);
found = 1;
}
}
return 0;
}
もとのは毎ループMD5の文字列表現を作ってましたが、こちらは逆に入力の文字列表現をMD5_Finalで作られるバイナリ値にして比較する方向。
$ clang-omp -O3 -fopenmp -lcrypto findmd5.c -o findmd5
$ ./findmd5 hoge 4b364677946ccf79f841114e73ccaf4f
real 0m0.065s
user 0m0.201s
sys 0m0.004s
と大分早くなりました。さっくり並列化できるOpenMPはすごいですね。