Я пытаюсь реализовать простой метод грубой силы, который расшифровывает зашифрованный пароль с двумя буквами и двумя цифрами, например. АА15. Это для моего проекта колледжа, и он требует использования многопоточности. Поэтому я создал две функции ядра и назначил их двум потокам. один поток будет расшифровывать от буквы A до M, а другой от N до Z. Этот код работал нормально, прежде чем я добавил многопоточность. Теперь метод crypt возвращает разные хэши одной и той же соли и ввода. Он отлично работает, если я использую только один поток.
Код выглядит следующим образом:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <crypt.h>
#include <time.h>
#include <pthread.h>
char pp[] = "$6$AS$KDz2YK3J483TubP5vGxy79Xa1cmV8e75Asy0ekjoV7HtuS7EAjnH.xWmVng0IhoIg12JEzlnHFcu9UzS1tbXk1";
char *encrypted_password = pp;
void substr(char *dest, char *src, int start, int length)
{
memcpy(dest, src + start, length);
*(dest + length) = '\0';
}
void *function()
{
pthread_t t1, t2;
void *kernel_function_1();
void *kernel_function_2();
pthread_create(&t1, NULL, kernel_function_1, (void *)(encrypted_password));
pthread_create(&t2, NULL, kernel_function_2, (void *)(encrypted_password));
pthread_join(t1, NULL);
pthread_join(t2, NULL);
}
void *kernel_function_1(char *salt_and_encrypted)
{
int h, i, j; // Loop counters
char salt[7]; // String used in hashing the password. Need space for \0
char plain[7]; // The combination of letters currently being checked
char *enc; // Pointer to the encrypted password
int count = 0; // The number of combinations explored so far
substr(salt, salt_and_encrypted, 0, 6);
for (h = 'A'; h <= 'M'; h++)
{
for (i = 'A'; i <= 'Z'; i++)
{
for (j = 0; j <= 99; j++)
{
sprintf(plain, "%c%c%02d", h, i, j);
enc = (char *)crypt(plain, salt);
count++;
if (strcmp(salt_and_encrypted, enc) == 0)
{
printf("#%-8d%s %s\n", count, plain, enc);
exit(0);
}
else
{
printf(" %-8d%s %s\n", count, plain, enc);
}
}
}
}
printf("%d solutions explored\n", count);
}
void *kernel_function_2(char *salt_and_encrypted)
{
int x, y, z; // Loop counters
char salt[7]; // String used in hashing the password. Need space for \0
char plain[7]; // The combination of letters currently being checked
char *enc; // Pointer to the encrypted password
int count = 0; // The number of combinations explored so far
substr(salt, salt_and_encrypted, 0, 6);
for (x = 'N'; x <= 'Z'; x++)
{
for (y = 'A'; y <= 'Z'; y++)
{
for (z = 0; z <= 99; z++)
{
sprintf(plain, "%c%c%02d", x, y, z);
enc = (char *)crypt(plain, salt);
count++;
if (strcmp(salt_and_encrypted, enc) == 0)
{
printf("#%-8d%s %s\n", count, plain, enc);
exit(0);
}
else
{
printf(" %-8d%s %s\n", count, plain, enc);
}
}
}
}
printf("%d solutions explored\n", count);
}
int time_difference(struct timespec *start, struct timespec *finish,
long long int *difference)
{
long long int ds = finish->tv_sec - start->tv_sec;
long long int dn = finish->tv_nsec - start->tv_nsec;
if (dn < 0)
{
ds--;
dn += 1000000000;
}
*difference = ds * 1000000000 + dn;
return !(*difference > 0);
}
int main(int argc, char *argv[])
{
struct timespec start, finish;
long long int time_elapsed;
clock_gettime(CLOCK_MONOTONIC, &start);
function();
clock_gettime(CLOCK_MONOTONIC, &finish);
time_difference(&start, &finish, &time_elapsed);
printf("Time elapsed was %lldns or %0.9lfs\n", time_elapsed,
(time_elapsed / 1.0e9));
return 0;
}
Я печатаю
склеп ч с
в гугл. Один из лучших хитов — документация по функции crypt.
Я прочитал документы.
Возвращаемое значение crypt() указывает на статические данные, которые перезаписываются при каждом вызове.
Таким образом, два потока совместно используют один внутренний буфер.
Функция crypt() не требует повторного входа. Функция, не требующая повторного входа, не обязана быть потокобезопасной.
Отсюда ваша проблема.
Я не вижу c++ в приведенном выше коде?