c - 我怎样才能让这个蛮力算法逐步检查字母

标签 c brute-force

对于此作业,我必须使用 C 语言中的 pthreads 来制作暴力密码破解程序。

下面的代码使用 for 循环生成一个 6 个字母的密码(最好是 8 个字母长),然后我使用 crypt_r 对其进行哈希处理,并将其与我在执行时为程序提供的哈希值和加盐值进行比较。

散列和盐在开始时被接收,存储在一个名为 dataStr 的结构中,然后将其提供给 pthreadCreate。

这看起来很简单,但即使我将数组 memset 为空终止字符,在执行时程序仍将整个内容设置为“aaaaaa”。这个问题是它忽略了 1-4 个字符长的密码。

这是我使用的数据结构:

typedef struct {

    char * hash;            //hashed code given in argv[1]
    char * salt;            //salt for hashed code given in argv[2]

    int start;              //starting char in alphabet for first letter
    int end;                //ending char in alphabet for first letter

    int id;                 //thread id

} dataStruct;

尺寸定义:

//Definitions
#define PW_SIZE 8
#define ALPHABET_SIZE 66
#define HASH_MAX_SIZE 128

这是代码本身

void * thread(void * arg) {

    struct timespec start, finish;          //Data structure for time.h library
    clock_gettime(CLOCK_MONOTONIC, &start); //Start chronometer
    double elapsed;

    struct crypt_data* cdata = (struct crypt_data *)malloc(sizeof(struct crypt_data));
    cdata->initialized = 0;

    dataStruct dataStr = *((dataStruct*)(arg)); //receive structure in arguement

    const char * alphabet = get_alphabet();     //create alphabet

    bool pw_found = false;                      //boolean used for 
    int retDone = 1;

    char * pwd = malloc(PW_SIZE * sizeof(char));
    memset(pwd, '\0', PW_SIZE);

    int i,j,k,l,m,n;

    for (i = dataStr.start; i <= dataStr.end; i++) {            
        for (j = 0; j <= ALPHABET_SIZE; j++) {
            for (k = 0; k <= ALPHABET_SIZE; k++) {
                for (l = 0; l <= ALPHABET_SIZE; l++) {
                    for (m = 0; m <= ALPHABET_SIZE; m++) {
                        for (n = 0; n <= ALPHABET_SIZE; n++) {

                            if (pw_found) {
                                clock_gettime(CLOCK_MONOTONIC, &finish);        
                                elapsed = finish.tv_sec - start.tv_sec;
                                elapsed += (finish.tv_nsec - start.tv_nsec) / 1000000000.0; 
                                printf("Time elapsed : %f sec(s) \n\n", elapsed);   //Time

                                pthread_exit(&retDone);                                 
                            }                           

                            pwd[0] = alphabet[i];   
                            pwd[1] = alphabet[j];   
                            pwd[2] = alphabet[k];
                            pwd[3] = alphabet[l];
                            pwd[4] = alphabet[m];
                            pwd[5] = alphabet[n];

                            printf("%s\n", pwd);

                            char * hash = crypt_r(pwd, dataStr.salt, cdata);

                            if (strcmp(hash, dataStr.hash) == 0) {
                                printf("\nPassword     : %s\n", pwd);
                                pw_found = true;
                            }
                        }
                    }
                }
            }
        }                       
    }

    pthread_exit(&retDone); 
}

这是它在执行时产生的结果:

enter image description here

我想了解如何以某种方式更改 6 个循环,以便让程序首先仅搜索 1 个字母字符,然后搜索 2 个,然后搜索 3 个,然后从那里递增。

感谢任何帮助。非常感谢!

PS - 我不介意通过电子邮件向某人发送全局 View 的代码。

最佳答案

可以使用指针来实现这一点。 ppw 将指向 pw 数组中的某处。 pch 将指向 characters 数组中的某处。递增 (++) 和递减 (--) 指针会在各自数组的元素内移动指针。 Dereferencing(*) 可以访问指针指向的值。 usedpw 中已使用的元素数。第一个元素从 0 开始,并向 SIZE 递增。 characters 可以修改为包括有效的字母、数字和符号。请注意不要重复。例如,如果字母 u 出现不止一次,程序将进入无限循环。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define SIZE 5

int main( void)
{
    char pw[SIZE + 1] = "";
    char *ppw = NULL;
    char *pch = NULL;
    char characters[] = "abcdefghijklmnopqrstuvwxyz";
    int used = 0;
    int out = 1;
    int last = strlen ( characters) - 1;

    //set pw
    pw[used] = characters[0];
    pw[used + 1] = '\0';

    while ( used < SIZE) {//loop until all elements of pw have been used
        ppw = &pw[used];//set ppw to point to last used element of pw
        while ( ppw >= pw) {//so ppw always points to an element of pw
            if ( ( pch = strchr ( characters, *ppw)) != NULL) {//get pointer into characters for current value that ppw point to
                if ( out) {//print when appropriate
                    printf ( "%s\n", pw);
                }
                if ( pch < &characters[last]) {//pch does not point to last element of characters
                    ++pch;//pch points to next element of characters
                    *ppw = *pch;//set what ppw points to to be the same as what pch points to
                    if ( ppw != &pw[used]) {//ppw is not pointing to last element of pw
                        ppw = &pw[used];
                    }
                    out = 1;//allow printing
                }
                else {//pch is pointing to last element of characters
                    *ppw = characters[0];//set what ppw points to to be the first element of characters
                    ppw--;//ppw points to next lower element of pw. ex from pw[n] to pw[n-1]
                    out = 0;//disable printing
                }
            }
        }//exit loop when ppw points to address less than pw
        used++;//increase elements in use
        memset ( pw, characters[0], used);//reset all elements to first element of characters
        pw[used + 1] = '\0';//just in case, terminate
    }//exit loop when all elements have been used

    exit ( 0);
}

这似乎有效。添加了两行以将 out 设置为 1,并将 used + 1 添加到对 memset 的调用。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// one more than the desired size
#define SIZE 4

int main( void)
{
    char pw[SIZE] = "";
    char *ppw = NULL;
    char *pch = NULL;
    char characters[] = "abc";
    int used = 0;
    int out = 1;
    int last = strlen ( characters) - 1;

    //set pw as character[0]
    pw[used] = characters[0];
    pw[used + 1] = '\0';

    while ( used < SIZE - 1) {//loop until all elements of pw have been used
        ppw = &pw[used];//set ppw to point to last used element of pw
        out = 1;
        while ( ppw >= pw) {//so ppw always points to an element of pw
            if ( ( pch = strchr ( characters, *ppw)) != NULL) {//get pointer into characters for current value that ppw point to
                if ( out) {//print when appropriate
                    printf ( "%s\n", pw);
                }
                out = 1;
                if ( pch < &characters[last]) {//pch does not point to last element of characters
                    ++pch;//pch points to next element of characters
                    *ppw = *pch;//set what ppw points to to be the same as what pch points to
                    if ( ppw != &pw[used]) {//ppw is not pointing to last element of pw
                        ppw = &pw[used];
                    }
                }
                else {//pch is pointing to last element of characters
                    *ppw = characters[0];//set what ppw points to to be the first element of characters
                    ppw--;//ppw points to next lower element of pw. ex from pw[n] to pw[n-1]
                    out = 0;//disable printing
                }
            }
        }//exit loop when ppw points to address less than pw
        used++;//increase elements in use
        memset ( pw, characters[0], used + 1);//reset all elements to first element of characters
        pw[used + 1] = '\0';//just in case, terminate
    }//exit loop when all elements have been used

    exit ( 0);
}

关于c - 我怎样才能让这个蛮力算法逐步检查字母,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40389271/

相关文章:

c++ - 是否有 itoa 版本返回写入缓冲区的字符数?

python - 创建一个Bruteforce程序,该程序可对随机非重复数字进行混洗。收到ValueError-不确定为什么吗?

algorithm - 有效地找到前 n 个素数

python-3.x - 蛮力子集总和解决方案抛出“设置”对象不是下标错误

c - 如何拦截C中的 "Windows - corrupt file"错误

c++ - 丢弃一个值会导致读取它吗?

c - 使用 libsqlite3 的间歇性段错误, "error 4 in libsqlite3.so.0.8.6"

c - 将 malloc 输出分配给地址?左值错误

python - 每次循环运行时的新字符串

python - 在 Django 中限制暴力登录攻击