Search code examples
cbrute-force

Having trouble with this bruteforce example program in C


I'm learning C right now and I'm quite new to it sorry for any simple mistakes, I wanted to make a brute force program where you enter a word in the console then the C program will make random guesses and compare them to the word you entered. Here's the code:

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

int main() {
    unsigned long guesses;
    char guess[100];
    char pass[100];
    char letter[100];
    const char letters[26] = "abcdefghijklmnopqrstuvwxyz";
    srand(time(NULL));
    printf("\ninput your password lowercase letters only: ");
    scanf("%99s", pass);
    while (strcmp(guess, pass) != 0) {
        //reset guess
        char guess[100] = {"\0"};
        //choose a random number 
        //copy a random element from var letters
        //concentrate the letter to the guess and repeat till its as long as the password
        while (strlen(guess) < strlen(pass)) {
            char i = rand() % 26;
            strcpy(letter, &letters[i]);
            strcat(guess, letter);
        }
        printf("%s\n", guess);
        guesses++;
    }
    printf("your guess was %s and was found in %lu guesses", guess, guesses);
    return 0;
}

and the output in the console is when I entered the word yes

qrstuvwxyz�
efghijklmnopqrstuvwxyz�
efghijklmnopqrstuvwxyz�
stuvwxyz�
efghijklmnopqrstuvwxyz�
qrstuvwxyz�
bcdefghijklmnopqrstuvwxyz�
hijklmnopqrstuvwxyz�
qrstuvwxyz�
qrstuvwxyz�

I'm not really sure why it does this if anyone can help it would be very appreciated

I tried many different ways of adding the letter to the guess but no matter what I try it adds many more letters then I need and the letters increment by 1 instead of being a new random character everytime


Solution

  • Testing out your code and tweaking it to make it functional, following is a refactored version of your code.

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <time.h>
    
    #define MAX 100
    
    int main()
    {
        unsigned long guesses = 0;
        char guess[MAX];
        char pass[MAX];
        char letter[2];
        const char letters[26] = "abcdefghijklmnopqrstuvwxyz";
        srand(time(NULL));
        printf("\nInput your password lowercase letters only: ");
        scanf("%s", pass);
        while (1)
        {
            // Reset guess
            for (int j = 0; j < MAX; j++)
            {
                guess[j] = '\0';
            }
            // Choose a random number
            // Copy a random element from var letters
            // Concentrate the letter to the guess and repeat till its as long as the password
            while (strlen(guess) < strlen(pass))
            {
                letter[0] = letters[rand() % 26];   /* Set up character string with one random character */
                letter[1] = '\0';
                strcat(guess, letter);
            }
            printf("%s\n", guess);
            guesses++;
            if (strcmp(guess, pass) == 0)
            {
                break;
            }
        }
    
        printf("your guess was %s and was found in %lu guesses\n", guess, guesses);
    
        return 0;
    }
    

    Some items to note in this tweaked version of your code.

    • When seeing repeated references to fixed values, it is usual and customary to utilize a "#define" declaration to cut down on literal values in the code.
    • Rather than making the test of the guess the true/false test for the "while" loop, a simple endless "while" loop is set up and then when a correct guess is made, a break from the loop is made to remove vagueness and any possible scope issues with the guess variable.
    • The "letter" string array is simplified to hold one character value along with a terminator character which simplifies the concatenation to the guess string array.

    With that, here is the last few output lines at the terminal when an entry of "bell" was used for the guess by the program.

    cjih
    nroe
    ppzk
    kyvi
    cofh
    bell
    your guess was bell and was found in 429653 guesses
    

    As noted in the good comments above, this brute force approach can take an incredible amount of time the longer the input value is. When I tested this program with a five-character literal, the program went on for a long time until I manually stopped the program. Therefore, there might be a ceiling test added to the number of attempts in this program.

    Anyway, you might give this refactored code a try and see if it meets the spirit of your project.