Iterating through all possible Letter combinations - c

Trying to crack password using brute force but program does not seem to realize when it found the password.
So I tried writing a little program to crack passwords using brute force.
basically I iterate rhough all letter combinations using nested for loops (The passwords needn't be longer than 4 letters), then I use crypt on the password with a given salt (assuming the salt is fixed) to check whether I cracked the password (I have access to the crypted passwords). Now I had the code output what it generates and it looks like it does iterate through all lowercase variants. But somehow it never find the password.
Now I have created the crypted version myself so I know the password is 4 Letters long, that’s not the problem and the program does seems to iterate through all possibilities, I think, so what could be the problem ? Is the if condition wrong ?
Now I guess this is not the most elegant solution for the problem but I think the general Idea is right. But if there is a problem with that nested for loop approach I'd be happy to know that to :).
#define _XOPEN_SOURCE
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <cs50.h>
int main(int argc, string argv[]) {
if(argc < 2) {
printf("Please enter a password to crack! \n");
return 1;
}
char s[4] = "";
for(int i = 0; i <=27; i++) {
if(i == 0)
s[0] = 0;
else
s[0] = i - 1 + 'a';
if(strcmp(crypt(s, "50"), argv[1]) == 0) {
break; }
for(int j = 0; j <=26; j++) {
if(j == 0)
s[1] = 0;
else
s[1] = (j - 1 + 'a');
if(strcmp(crypt(s, "50"), argv[1]) == 0)
break;
for(int k = 0; k <= 26; k++) {
if(k == 0)
s[2] = 0;
s[2] = (k - 1 + 'a');
if(strcmp(crypt(s, "50"), argv[1]) == 0)
break;
for(int l = 0; l <= 26; l++) {
printf("%s \n", s);
if(l == 0)
s[3] = 0;
else
s[3] = (l - 1 + 'a');
if(strcmp(crypt(s, "50"), argv[1]) == 0)
break;
}
}
}
}
if (strcmp(crypt(s, "50"), argv[1]) != 0)
printf("Password not found");
else
printf("%s \n", s);

Declaring char s[4] fails to leave room for a null character terminator when the array has four non-null characters, resulting in behavior not defined by the C standard.

C strings are null terminated, that means, that a string in C is basically an array of bytes/characters (like the one you initialize: char s[4] = "";) with the last byte set to 0.
strcmp goes through two strings(byte arrays) and compares them one by one until it finds a different character or until both strings end, i.e. the currently compared byte is a 0 for both strings. When you initialize your char array s to be 4 bytes, and write 4 non-null bytes into it, strcmp will continue comparing bytes after the end of the array, because it did not hit the end of a string. This can also crash your program or lead to security vulnerabilities, because you continue reading into memory, that you are not supposed to. To get around this, properly terminate your input strings with a null byte and use the strncmp function when possible, which takes an additional parameter, indicating how many characters it should compare at most.
As you correctly identified, the nested loop approach is not the most elegant solution, because you are repeating yourself over and over and the resulting code is very rigid and can only compare up to 4 character passwords. It would be cleaner to have an outer for loop to loop through the possible passwords lengths and then call a function which checks all possible passwords of a certain length (using two nested loops).
If you are just looking to bruteforce some passwords and not actually want to program it yourself, you will probably be better of using some professional tool like https://hashcat.net/hashcat/.

Related

How to remove dash from a string, using C? [duplicate]

This question already has answers here:
Remove characters from a string in C
(4 answers)
How to remove the character at a given index from a string in C?
(22 answers)
Closed 1 year ago.
C is a new language for me. So some things I learned in other languages don't work here. I created a program that reads a string from the user, and what happens is when there is a dash (-) in the string, I want to remove it, just remove it, I tried to do that by the conventional method var x = "", but it didn't work. Sure, that's just an example, I know it doesn't work in C, but you got the idea.
Source code
#include <stdio.h>
#include <string.h>
int main()
{
char input[50];
int i;
scanf("%s", input);
for (i = 0; i < strlen(input); i++)
{
if (input[i] == '-')
{
input[i] = "" // Does not remove the dash
}
}
printf("%s\n", input);
return 0;
}
I also tried: input[i] = '\0' and it does not work as well. How can I fix it?
Example of how I want it to be:
Input: 333-55792
Output: 33355792
C is not a high level language. You need to do the manual work of shifting the characters to left skipping dashes:
int from = 0;
int to = 0;
while (str[from] != '\0')
{
if (str[from] == '-')
{
++from;
continue;
}
str[to] = str[from];
++to;
++from;
}
str[to] = '\0';
I don't see a very simple answer in the duplicate. Removing single characters is much easier than removing strings of characters, since we can easily find them.
I will point out that you should not call strlen a lot in C. strlen counts all the characters, so it is O(n), making your loop O(n^2). C uses null terminated strings, so inserting a '\0' ends the string. You can also use this fact to terminate your loop.
There are easier ways to do this using pointers, but for a beginner, I'll give an array like solution
int dashes = 0;
for (i = 0; input[i] != '\0'; i++)
{
if (input[i] == '-')
{
dashes++;
}
else if (dashes > 0)
{
input[i-dashes] = input[i];
}
}
// now, null terminate, could do this changing our loop test, but
// this is easier to understand.
input[i-dashes] = '\0';

Hello i got an assignment in c programing and i dont really understand the c/malloc function i think

Hello i got an assignment in c programing and i dont really understand the c/malloc function i think,
they told us that we need to do the free function after using this function, but every time i do free it breaks the program
The assignment is :
collect an input string.
every upper case letter to lower
every lower case letter to upper
if there is number do series of numbers from '9' until the input number but with out it (for '6' do '9','8','7'. (with out 6))
if there is other stuff don't add it in to the out put.
input example : A$q6#G4
output example : aQ987g98765
it is not allowed to change the input string.
in the input allowed to be every thing.
the output sting needs to be exactly in the array size
(if 123 = the size of will be input[2])
photo of the error
the error : wntdll.pdb contains the debug information required to find the source for the module ntdll.dll
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
/* Function declarations */
char Ex1FNumbers(char);
char Ex1FLetters(char);
/* ------------------------------- */
//
int main()
{
system("cls"); //delete when send
int select = 0, i, all_Ex_in_loop = 0;
printf("Run menu once or cyclically?\n(Once - enter 0, cyclically - enter other number) ");
if (scanf_s("%d", &all_Ex_in_loop) == 1)
do
{
for (i = 1; i <= 3; i++)
printf("Ex%d--->%d\n", i, i);
printf("EXIT-->0\n");
do {
select = 0;
printf("please select 0-3 : ");
scanf_s("%d", &select);
} while ((select < 0) || (select > 3));
switch (select)
{
case 1: //Ex1
{
int size, i, n, counter = 0;
char inPut[] = "";
char outPut[] = "";
char* Ptr_inPut_address, * Ptr_outPut_address, num;
printf("Please enter a string :\n");
scanf("%s", inPut);
size = strlen(inPut);
Ptr_outPut_address = &outPut;
Ptr_inPut_address = (char*) calloc(size+1 , sizeof(char));
Ptr_outPut_address = (char*) calloc(0, sizeof(char));
if (!Ptr_inPut_address || !Ptr_outPut_address)
{
break;
}
for (i = 0; i < size; i++)
{
Ptr_outPut_address = (char*)realloc(Ptr_outPut_address, counter);
if (inPut[i] >= 'a' && inPut[i] <= 'z' || inPut[i] >= 'A' && inPut[i] <= 'Z')
{
if (inPut[i] >= 'a' && inPut[i] <= 'z')
{
outPut[counter++] = inPut[i] - 32;
}
else
{
outPut[counter++] = inPut[i] + 32;
}
}
else if (inPut[i] <= '9' && inPut[i] >= '0')
{
n = '9' - inPut[i];
Ptr_outPut_address = (char*)realloc(Ptr_outPut_address, counter + n);
for (n; n > 0; n--) // "o" of 8 and not "n" because 8 is the max num for this "for".
{
outPut[counter++] = inPut[i] + n;
}
}
}
Ptr_outPut_address = (char*)realloc(Ptr_outPut_address, counter);
outPut[counter] = '\0';
Ptr_outPut_address = &outPut;
printf("%s\n", Ptr_outPut_address);
if (Ptr_outPut_address != NULL)
{
free(Ptr_outPut_address);
}
if (Ptr_inPut_address != NULL)
{
free(Ptr_inPut_address);
}
} break;
case 2: //Ex2
{
}break;
case 3: //Ex3
{
}break;
}
} while (all_Ex_in_loop && select);
system("pause");//delete when send
main();//delete when send
//return 0; // return when send
}
char inPut[] = "";
char outPut[] = "";
This declares two arrays that contain exactly one char, initializing them to '\0'. That's what the above means in C. This does not mean that these two arrays will have infinite size and can store any string. That's not how this works. But then, immediately afterwards:
scanf("%s", inPut);
This is guaranteed to overflow the array, since it is capable of holding only one char. Any string this reads will have at least two chars: the single read character, followed by '\0'. This results in memory corruption and undefined behavior.
There are several other bugs in the shown code. One more example:
Ptr_outPut_address = &outPut;
This has the effect of setting this variable to the starting address of a char array that was declared earlier.
Ptr_outPut_address = (char*)realloc(Ptr_outPut_address, counter);
You can only realloc something that was malloced, realloced, or calloced. No exceptions. You cannot realloc anything else. The char array was not malloced, realloced, or calloced. C does not work this way.
Several other problems exists in the shown code. Looks like this entire program was written all at once, before an attempt was made to test everything. This approach is very unlikely to succeed, and will likely produce many different kinds of bugs, such as the one that I've described. This makes it difficult to analyze and fix everything, since you're not looking for just one bug, but an unknown number of bugs. Plus it is likely that there will be an eventual realization that some or most of what was written need to be rewritten from scratch since the shown approach turned out to be fundamentally wrong.
Which is what you should probably do: start from scratch, write only a few lines of code, before testing them, and making sure that they work correctly before proceeding to write more code. If you attempt to fix just the problems that I explained it's likely that this will just create other problems, additionally, there are other problems as well, I just didn't mention them. The entire approach that was used here needs to be changed, fundamentally.

Array with stopping condition

The task is: a user types an char array and the programm stops when the last two values make a match with the first and second inserted values, then it prints only inserted int values.
For example, I type: 1,2,f,5,2,g,s,d,c,3,1,2
And get 1,2,5,3
This what I've got for now
int main()
{
setlocale(LC_ALL, "RUS");
char* A;
int i = 2, N;
//making an array
A = (char*)malloc(2 * sizeof(char));
printf("Enter an array \n");
//entering the first value
scanf_s("%c", &A[0]);
//second value
scanf_s("%c", &A[1]);
//next values
while (!(A[i - 1] == A[0] && A[i] == A[1]))
{
i++;
A = (char*)realloc(A, (i + 1)*sizeof(char));
scanf_s("%c", &A[i]);
}
system("pause");
return 0;
}
So now it makes a stop only if the first value makes a match and prints nothing. I am really confused
You can avoid dynamically allocating altogether and just focus on the logic of your task. While you can use scanf for reading character input, you are better served using a character-oriented input function such as getchar.
That said, it appears you want to read characters from stdin, only storing unique digits in your array, and then if the user enters digits that match your first two elements stored in your array, print the values stored in the array and exit. (If I have any of that wrong, please let me know in a comment)
First off, reading characters with scanf can be a bit finicky depending on the values separating the character. However since you are only concerned with storing digits, that makes things a bit easier.
To avoid dealing with malloc, just set some reasonable limit to size your array and check your stored elements against. A simple #define is all you need. For example:
#define MAXE 128
Will define a constant MAXE (for max elements), to test against as you fill your array. Just keep a count of the elements you add to the array, and if you reach your limit, exit.
You want to keep reading characters until one of two conditions are met: (1) you have added 128 values to your array with no exit condition tripped, or (2) the last two characters entered match the digits store in a[0] and a[1]. To set up your read you can do something like:
while (n < MAXE && scanf ("%c", &c) == 1) { ...
note: with getchar() you can avoid the non-portable _s function issue, among other pitfalls with the scanf family of functions. The changes are minimal to use getchar() instead of declaring c as type char, declare c as type int, and then change your assignment to c as follows:
while (n < MAXE && (c = getchar()) != EOF) {
After reading a character, (regardless of how), you want to test whether it is a digit, if not you are not storing it and it can't be part of your exit condition. So you can simply get the next char if it isn't a digit:
if (c < '0' || '9' < c)
continue;
(note: ctype.h provides the isdigit() function that can be used instead of the manual checks)
You want to store the first two digit regardless, and following those two, you want to store any new digits entered (not already stored), so you need to test the current digit against all digits previously stored to insure it is a unique digit. While you can code the logic several ways, in this case your test loop must test all values stored before making a decision to store the current digit. In this situation, and in situations where you need to break control within nested loop, the lowly goto statement is your best friend. Here if the digit is a duplicate, the goto simply skips to the dupes label passing over the assignment:
if (n > 1)
for (i = 0; i < n; i++)
if (c == a[i])
goto dupe;
a[n++] = c;
dupe:;
The last part of the puzzle is your exit condition. This is a bit tricky (but simply solved) because you know you will not store the preceding (or for Leffler, the penultimate) value in the array to test against (it being non-unique to the array). The trick is just to save the character from the last iteration to test against. (maybe in a variable called last). Now you can code your exit clause:
if (n > 2 && a[0] == last && a[1] == c)
break;
Putting it all together, you could do something like the following:
#include <stdio.h>
#define MAXE 128
int main (void) {
char a[MAXE] = "", c, last = 'a';
int i, n = 0;
printf ("Enter an array\n");
while (n < MAXE && scanf ("%c", &c) == 1) {
if (c < '0' || '9' < c)
continue;
if (n > 1)
for (i = 0; i < n; i++)
if (c == a[i])
goto dupe;
a[n++] = c;
dupe:;
if (n > 2 && a[0] == last && a[1] == c)
break;
last = c;
}
if (n < 3) {
fprintf (stderr, "error: minimum of 3 values required.\n");
return 1;
}
if (n == MAXE) {
fprintf (stderr, "warning: limit of values reached.\n");
return 1;
}
printf ("Values in array: ");
for (i = 0; i < n; i++)
putchar (a[i]);
putchar ('\n');
return 0;
}
How you handle the printing and error conditions are up to you. Those included above are just a thought on how you could cover your bases.
Note: gcc does not implement the optional _s functions, so you can make the change back to scanf_s if you need to.
Example Use/Output
$ ./bin/exitonmatch
Enter an array
1
2
f
5
2
g
s
d
c
3
1
2
Values in array: 1253
Look it over and let me know if you have any questions.
Accept Any Char as Termination/Store only Unique Digits
If the logic as you have explained, is to track the first two characters, regardless of whether they are digits and allow any character to serve as the termination check of first two entered sequence, the easiest way to handle that is to simply store the first two characters entered in a separate array (or two variables) and check each sequence of characters entered against them.
Adding this type check takes no more than a slight rearranging of the conditions in the original to allow a few checks on any character entered before considering only digits for storage in your array.
note: the cc (character count) variable was added to track the number of characters entered and the first array was added to hold the first two characters entered.
For example:
char a[MAXE] = "", first[TSTA] = "", last = 'a';
int c, cc = 0, i, n = 0;
printf ("Enter an array\n");
while (n < MAXE && (c = getchar()) != EOF) {
if (c < ' ') continue; /* skip non-print chars */
if (cc < 2) /* fill first[0] & [1] */
first[cc] = c; /* check term condition */
if (++cc > 2 && first[0] == last && first[1] == c)
break;
last = c; /* set last */
if (c < '0' || '9' < c) /* store only numbers */
continue;
if (n > 1) /* skip duplicates */
for (i = 0; i < n; i++)
if (c == a[i])
goto dupe;
a[n++] = c; /* digit and not a dupe - store it */
dupe:;
}
note: getchar is used above, but you can substitute scanf from the first example if you like.
Example Use/Output
Here there first two characters are a and b which serve as the termination sequence despite not being digits.
$ ./bin/exitonmatchgc
Enter an array
a
b
c
4
5
g
h
4
9
3
b
a
b
Values in array: 4593

C: Output with symbols in Caesar’s cipher encrypts, WHY? pset2 cs50

This is Caesar’s cipher encrypts problem in pset2 of cs50x course in edx.org.
I already solved this problem with another algorithm but this was my first try and I'm still curious why appear all these symbols at the right side of the caesar text.
ie. I enter the text "Testing" and the output is "Fqefuz�����w����l��B��" but the answer is correct without the symbols.
Can anyone explain me that?
int main(int argc, string argv[])
{
bool keyOk = false;
int k = 0;
do
{
if(argc != 2) // Checking if the key was correctly entered.
{
printf("You should enter the key in one argument from"
" the prompt(i.e. './caesar <key>').\n");
return 1;
}
else
{
k = atoi(argv[1]); // Converting string to int.
keyOk = true; // Approving key.
}
}
while(keyOk == false);
string msg = GetString(); // Reading user input.
char caesarMsg[strlen(msg)];
for(int i=0, n = strlen(msg); i < n; i++)
{
if( (msg[i] >= 'a') && (msg[i] <= 'z') )
// Processing lower case characters
{
caesarMsg[i] = ((((msg[i] - 97) + k) % 26) + 97);
}
else if( (msg[i] >= 'A') && (msg[i] <= 'Z') )
// Processing upper case characters
{
caesarMsg[i] = ((((msg[i] - 65) + k) % 26) + 65);
}
else
{
caesarMsg[i] = msg[i];
}
}
printf("%s", caesarMsg);
printf("\n");
}
The root problem is C does not have a full, proper, or first-class "string" datatype. In C strings are in fact character arrays that are terminated with the NUL ('\0') (*) character.
Look at
string msg = GetString(); // Reading user input.
char caesarMsg[strlen(msg)];
This is equivalent to
char* msg = GetString(); /* User or library function defined elsewhere */
/* calculates the length of the string s, excluding the terminating null
byte ('\0') */
size_t len = strlen(msg);
char caesarMsg[len]; /* Create an character (byte) array of size `len` */
Hopefully this makes it clearer, why this section fails to work correctly. The variable len that I've added, is the length of the sequence of non-NUL characters in the string msg. So when you create the character array caesarMsg of length len, there is no room for the NUL character to be stored.
The for loop correctly executes, but the printf("%s", caesarMsg); will continue to print characters until it finds a NUL or crashes.
BTW you can reduce the two printf statements at the end into a single printf statement easily.
printf("%s\n", caesarMsg);
Strings and character arrays are a frequent source of confusion to anyone new to C, and some not-so-new to C. Some additional references:
I really recommend bookmarking is the comp.lang.c FAQ.
I also strongly that you have either get your own copy or ensure you have access to Kernighan and Ritchie's The C Programming Language, Second Edition (1988).
Rant: And whoever created the string typedef is evil / making a grave error, by misleading students that into thinking C's strings are are a "real" (or first-class) data type.
(*) NUL is different from NULL, because NULL (the null-pointer) is cast as a pointer as so it the same size as other pointers, where as NUL is a null-character (and either the size of a char or int).

Compare two strings character by character in C

I have one 'simple' (I hope) question. I am actually coding some little program and I need to compare two strings, same length, but different letters like
Eagle
and
Hdjoh
I want to compare the first letter of the first string with the first letter of the second string,
the second letter of the first string with the second letter of the second string etc..
I started to do like this:
for(i=0, i<N, i++){
for(j=0, j<N, j++){
if(string1[i]==string1[j] etc.. etc..
}
}
I see clearly that it doesn't compare first letter with first letter, second with second etc..
So maybe anyone have an idea how can I do this? (Without using any functions of string.h, i want to do this ''on my own'').
Maybe its a stupid question but im still a novice in C so...
Ah and the last thing, I define the two strings with 5 characters in my example, but it could be more than 5 vs 5..
Thanks by advance for the ideas.
Edit 1 :
#include <stdio.h>
#define N 20
int main()
{
unsigned char string1[N], string2[N];
int Answer=0, i=0;
scanf("%s", string1);
scanf("%s", string2);
for(i=0; i<N; i++){
if(string1[i]==string2[i]){
Answer=1;
}
else{
Answer=0;
}
}
printf("Answer = %d", Answer);
return 0;
}
Why are you using a nested for loop for this? If both strings are of size n do this:
for(int i=0;i<n;i++){
if(string1[i]==string2[i]){
//do something
else if(// lesser than condition)
//do something else
else if(//greater than condition)
//do something else other than the previous something
}
Here you when i=0, you are comparing string1[0] with string2[0], when i=1, you compare string1[1] with string2[1] and so on.....
Your approach with nested loops isn't very well thought-out.
Clearly it will compare all letters of the second string against the first letter of the first string, then do the same for the second letter of the first string, and so on. Not at all the desired behavior.
Re-implementing strcmp() isn't very hard, here's a shot:
int my_strcmp(const char *a, const char *b)
{
for(; *a && *b && *a == *b; ++a, ++b)
;
if(*a < *b)
return -1;
return *a > *b;
}
Note that it returns zero when the strings are equal. A good way to write a test is:
if(my_strmcp(a, b) == 0)
{
printf("two equal strings: '%s' and '%s'\n", a, b);
}
Some people write it as if(!my_strcmp()) but I don't recommend that, since it's mashing up so many concepts.
You want to use the same index for both strings to compare:
unsigned len = strlen(s1);
assert(len == strlen(s2) && "Strings not the same length");
for (unsigned i = 0; i < len; i += 1)
{
if (s1[i] != s2[i])
return false; /* strings are not equal */
}
return true; /* strings are equal */
Make sure that the strings have the same encoding, either ASCII or UTF8 or whatever. Comparing strings of different encoding will cause trouble :)
This code compares character by character. Note that this is not suitable for crypto code as it is vulnerable to a timing attack
for(i=0; i<N; i++){
if(string1[i]==string2[i]){
equal = 1;
}else{
equal = 0;
break;
}
}
Notes:
I am assuming same length (as stated in question)
I am also assuming strings are non-zero length
Both of these assumptions may not be true in other code.
Simple compare each element until the end of string is found or a difference.
size_t i = 0;
while (string1[i] != '\0' && string1[i] == string2[j]) i++;
int StringTheSame = string1[i] == string2[j];
This ignores N, but stops when either end-of-string ('\0') is encountered.
[Edit] #Kartik_Koro suggested a concern about a timing attack. Following is a constant time solution
int diff_bits = 0;
for(size_t i=0; i<N; i++) {
diff_bits |= string1[i] ^ string2[i];
}
int equal = diff_bits == 0;
The above has a problem if either string's length is shorted than N-1, but per OP's requirements, that should not happen.

Resources