I am creating a simple md5 bruteforce-like program using C. The only issue I am having is that the Found String: output completely changes if I were to replace a part of the if statement.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <time.h>
#include <stdbool.h>
#if defined(__APPLE__)
# define COMMON_DIGEST_FOR_OPENSSL
# include <CommonCrypto/CommonDigest.h>
# define SHA1 CC_SHA1
#else
# include <openssl/md5.h>
#endif
char *str2md5(const char *str, int length) {
int n;
MD5_CTX c;
unsigned char digest[16];
char *out = (char*)malloc(33);
MD5_Init(&c);
while (length > 0) {
if (length > 512) {
MD5_Update(&c, str, 512);
} else {
MD5_Update(&c, str, length);
}
length -= 512;
str += 512;
}
MD5_Final(digest, &c);
for (n = 0; n < 16; ++n) {
snprintf(&(out[n*2]), 16*2, "%02x", (unsigned int)digest[n]);
}
return out;
}
typedef struct md5data {
char* output;
char* strin;
} md5data;
md5data getrand() {
for (int i = 0; i < 10; ++i)
{
rand();
srand(rand());
}
unsigned char strin[50];
for (int i = 0; i < 50; i++)
{
strin[i] = (rand()%94)+32;
}
strin[49] = '\0';
char* string = &strin;
char *output = str2md5(string, strlen(string));
md5data out;
out.output = output;
out.strin = string;
return out;
}
bool starts_with(const char* a, const char* b)
{
if(strncmp(a, b, strlen(b)) == 0) return 1;
return 0;
}
int main() {
char input;
printf("%s","Enter Search String: ");
scanf("%s",&input);
srand(time(NULL));
while(1 == 1) {
md5data md5 = getrand();
if(starts_with(md5.output,&input)) {
printf("Found String: %s\nMD5: %s\n",md5.strin,md5.output);
break;
}
}
return 0;
}
Whenever I compile and execute, the first line of output is usually something like Found String: 0????
However, if I change starts_with(md5.output,&input) to something like 1==1 or anything like that, the output is something like Found String: qM39$dcX_ZqFM9]?>jKhxSl#m2xrAxaL*
What is causing the output to change and why is it happening?
The problem is on lines:
char input;
printf("%s","Enter Search String: ");
scanf("%s",&input);
input should be a char array (a buffer), and not a single char.
For example:
char input[256];
printf("%s","Enter Search String: ");
scanf("%s",&input);
In the current state, the scanf results in a buffer overflow on your stack, which causes undefined results.
I ended up fixing this issue by adding a global variable, removing md5data, and using strcpy to copy the value form getrand into the global variable.
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <time.h>
#include <stdbool.h>
#if defined(__APPLE__)
# define COMMON_DIGEST_FOR_OPENSSL
# include <CommonCrypto/CommonDigest.h>
# define SHA1 CC_SHA1
#else
# include <openssl/md5.h>
#endif
char *str2md5(const char *str, int length) {
int n;
MD5_CTX c;
unsigned char digest[16];
char *out = (char*)malloc(33);
MD5_Init(&c);
while (length > 0) {
if (length > 512) {
MD5_Update(&c, str, 512);
} else {
MD5_Update(&c, str, length);
}
length -= 512;
str += 512;
}
MD5_Final(digest, &c);
for (n = 0; n < 16; ++n) {
snprintf(&(out[n*2]), 16*2, "%02x", (unsigned int)digest[n]);
}
return out;
}
unsigned char stringglobal[50];
char* outputglobal;
void getrand() {
for (int i = 0; i < 10; ++i)
{
rand();
srand(rand());
}
unsigned char strin[50] = {0};
for (int i = 0; i < 50; i++)
{
strin[i] = (rand()%94)+32;
}
strin[49] = '\0';
char* string = &strin[0];
char *output = str2md5(string, strlen(string));
outputglobal = output;
strcpy(stringglobal,string);
}
bool starts_with(const char* a, const char* b)
{
if(strncmp(a, b, strlen(b)) == 0) return 1;
return 0;
}
int main() {
char input[256];
printf("%s","Enter Search String: ");
scanf("%s",&input);
srand(time(NULL));
while(1 == 1) {
getrand();
if(starts_with(outputglobal,&input)) {
printf("Found! String: %s\nMD5: %s\n",stringglobal,outputglobal);
break;
}
}
return 0;
}
Related
I am trying to write code where I can separate string and numbers.
The string I have to separate it completely already the numbers I have to separate every 2 numbers.
My Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
void getString(const char *str) {
char nums[50];
char alphas[50];
for (int i = 0; i < strlen(str); i++) {
if (isdigit(str[i]))
strcpy(nums, str);
if (isalpha(str[i]))
strcpy(alphas, str);
}
printf("str: %s\n", alphas);
printf("num: %d\n", atoi(nums));
}
int main() {
char *str = "one01two02three03";
getString(str);
return 0;
}
What I'm trying to do should return me as follows
str: onetwothree
num1: 01
num2: 02
num3: 03
The following parses the input and produces the correct output.
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
int *nums = NULL;
int num_count = 0;
char save_num(int n)
{
nums = realloc(nums, sizeof(int)*(num_count+1));
nums[num_count++] = n;
return '\0';
}
void getString(const char *str)
{
char* alpha = malloc(strlen(str)+1);
char* num = malloc(strlen(str)+1);
size_t i;
alpha[0] = '\0';
num[0] = '\0';
for (i = 0; i < strlen(str); i++)
{
if (isdigit(str[i]))
strncat(num, str+i, 1);
else if(isalpha(str[i]))
{
strncat(alpha, str+i, 1);
if(strlen(num) > 0)
num[0] = save_num(atoi(num));
}
}
if(strlen(num) > 0)
save_num(atoi(num));
printf("str: %s\n", alpha);
for(i = 0 ; i < num_count ; ++i)
printf("num%Zu: %02d\n", i+1, nums[i]);
free(alpha);
free(num);
}
int main()
{
char *str = "one01two02three03";
getString(str);
return 0;
}
This provides what you have asked for:
void getString(const char *str)
{
char one[10],two[10],three[10];
int x,y,z;
char a[10],b[10],c[10];
sscanf(str,"%[^0-9]""%[0-9]""%[^0-9]""%[0-9]""%[^0-9]""%[0-9]",a,one,b,two,c,three);
x = atoi(one);
y = atoi(two);
z = atoi(three);
printf("str: %s%s%s\n",a,b,c);
printf("num: %d\n",x);
printf("num: %d\n",y);
printf("num: %d\n",z);
}
DonĀ“t forget to provide the declaration of getString before main():
void getString(const char *str);
So all together:
#include <stdio.h>
void getString(const char *str);
int main()
{
char *str = "one01two02three03";
getString(str);
return 0;
}
void getString(const char *str)
{
char one[10],two[10],three[10];
int x,y,z;
char a[10],b[10],c[10];
sscanf(str,"%[^0-9]""%[0-9]""%[^0-9]""%[0-9]""%[^0-9]""%[0-9]",a,one,b,two,c,three);
x = atoi(one);
y = atoi(two);
z = atoi(three);
printf("str: %s%s%s\n",a,b,c);
printf("num: %d\n",x);
printf("num: %d\n",y);
printf("num: %d\n",z);
}
Output:
str: onetwothree
num: 01
num: 02
num: 03
Since you have already set your strings 'nums' and 'alphas' there is no need to handle them dynamically.You should just copy the elements of the array str,one by one, to either the array num or the array alphas.
To distinguish different numbers just put a special character between numbers in the num array.
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
void getString(const char *str)
{
char nums[50];
char alphas[50];
int digits = 0;
int alpha = 0;
for (int i = 0; i < strlen(str); i++) {
if (isdigit(str[i])){
while(isdigit(str[i])){
nums[digits] = str[i];
i++;
digits++;
}
nums[digits]='\n';
digits++;
}
if(isalpha(str[i])){
alphas[alpha] = str[i];
alpha++;
}
}
printf("str: %s\n", alphas);
int n,p=0;
char subbuf[5];
for(n=0;n<digits;n++){
p=n;
while(nums[n]!='\n'){
n++;
}
memcpy(subbuf,&nums[p],n-p);
printf("num: %d\n", atoi(subbuf));
}
}
int main()
{
char *str = "01two02three03";
getString(str);
return 0;
}
Be aware that strcpy sets the pointer of the first argument to point to the second argument,this means that when you write strcpy(nums,str) in your code above, you copy the entire str string to the num several times.
Using an array for this question is not necessary, unless the array is to be used later. So my answer to this question is short and simple:
#include <stdio.h>
#include <stdbool.h>
void getString(const char *str)
{
bool in_number = false;
while (*str) {
if (*str >= '0' && *str <= '9') {
if (!in_number) { // Transition from a non-digit to digit
printf(": ");
in_number = true;
}
} else if (in_number) { // Transition from a digit to non-digit
putchar('\n');
in_number = false;
}
putchar(*str++);
}
putchar('\n');
}
int main(void)
{
char *str = "one01two02three03";
getString(str);
return 0;
}
The boolean variable in_number is used to catch the transitions from a digit character to a non-digit character and from a non-digit character to a digit character.
I wanna ask how it can not get integer from a string
for example, here are my code:
int main() {
char str[] = "ababbababa-1998";
int nr = atoi(str);
printf("%d\n", nr);
return (EXIT_SUCCESS);
}
when running, it print out 0 but not 1998, how can I fix it ?
In your case you can use strtok.
int main() {
char str[] = "ababbababa-1998";
char * const first_part = strtok(str, "-");
if (first_part == NULL) {
return 1;
}
char * const second_part = strtok(NULL, "-");
if (second_part == NULL) {
return 1;
}
int nr = atoi(second_part);
printf("%d\n", nr);
return 0;
}
You can look at Why is there no strtoi in stdlib.h? for error check atoi.
Keep walking down str() until code finds something numeric using strtol().
int main() {
char str[] = "ababbababa-1998";
char *p = str;
char *endptr;
while (*p) {
long number = strtol(p, &endptr, 10);
// Was conversion successful?
if (endptr != p) {
printf("%ld\n", number);
return EXIT_SUCCESS;
}
p++;
}
puts("No conversion");
return EXIT_FAILURE;
}
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define ASCII '0'
int
main(void) {
char const str[] = "ababbababa-1998";
int i, result = 0;
for (i = 0; str[i]; i++) {
if (isdigit(str[i])) {
result *= 10;
result += str[i] - ASCII;
}
}
printf("number = %d\n", result);
return 0;
}
If you want to extract all the numeric digits from a string you could use this function I created.
You will need these header files for this function to work.
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
void getNumbers(char data[]) {
int index = 0;
char current;
for( int i = 0; i < strlen(data); ++i ) {
current = data[i];
if (current >= 48 && current <= 57) {
data[index++] = current;
}
}
data[index] = '\0';
}
You can use the above function like this.
char foobar[] = "1A2B3C4D5E6F7G8H9I";
getNumbers(foobar);
printf("%s", foobar);
The above code will output 123456789
I have a little tiny trouble with implementing a shift. Here is the idea of what I'm trying to do:
Given a string of number like 012345, given a specific condition, the sequence will shift from
012345
001234.Can somebody show me why the code didn't work and how can I fix this.
for(int a = i; a < (strlen(input)); a++)
if (a < strlen(input) - 2)
{
holder = key[a+1];
key[a+1] = key[a];
key[a+2] = holder;
}
}
To shift right a string you can do:
#include <stdio.h>
#include <stdint.h>
#include <string.h>
void shift_r_str (char *string, size_t len, uint8_t shift);
int main(void)
{
char input[] = "012345";
shift_r_str(input, strlen(input), 1);
printf("Shifted: %s\n", input);
shift_r_str(input, strlen(input), 2);
printf("Shifted: %s\n", input);
}
void shift_r_str (char *string, size_t len, uint8_t shift)
{
size_t i;
if (len < shift)
{
shift = len;
}
for (i=len-1; ((i>0) && (i>=shift)); i--)
{
string[i] = string[i-shift];
}
for (i=0; i<shift; i++)
{
string[i] = '0';
}
}
Output will be:
Shifted: 001234
Shifted: 000012
I am having trouble making an array equal another array in c.
in the main method it will not let me assign inputInt1 to the returned value of converTwosComp.
#include <stdio.h>
#include <stdlib.h>
int validChecker(char *input_StringIn);
int* convertTwosComp(char *inputStringIn, int *inputIntIn);
int main(void) {
char inputString1[11];
char inputString2[11];
int inputInt1[11];
int inputInt2[11];
printf(" is ");
inputInt1 = convertTwosComp(inputString1, inputInt1);
for(i = 0; inputString1[i]; i++){
printf("%d", inputInt1[i]);
}
int * convertTwosComp(char *inputStringIn, int *inputIntIn){
int digit;
int i;
if((inputStringIn[0] == '+') ||(inputStringIn[0]) == '0'){
inputStringIn[0] = 0;
}
if(inputStringIn[0] == '-'){
inputStringIn[0] = 1;
}
for(i = 0; inputStringIn[i]; i++){
digit = inputStringIn[i] - '0';
inputStringIn[i] = digit;
}
for(i = 0; inputIntIn[i]; i++){
if(inputIntIn[i] == 0){
inputIntIn[i] = 1;
}
if(inputIntIn[i] == 1){
inputIntIn[i] = 0;
}
}
return inputIntIn;
}
in the main method it will not let me assign inputInt1 to the returned value of converTwosComp.
This is what you probably need:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void){
char array1[] = "Michi";
size_t len = strlen(array1);
char *array2 = malloc(len+1);
memcpy(array2, array1, len+1);
printf("Array2 = %s\n",array2);
free(array2);
return 0;
}
Output:
Array2 = Michi
You can always use a for loop to copy a string, in case you do not want to use memcpy.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char one[30];
char two[30];
while(fgets(one,sizeof(one),stdin))
{
int len = strlen(one);
for(int i = 0; i < (len + 1); i++)
{
two[i] = one[i];
}
printf("%s", two);
break;
}
return EXIT_SUCCESS;
}
I was planning on creating an encryption program. Basically swap anything that is from the normal "abcdefghijklmnopqrstuvwxyz" to ""thequickbrownfxjmpsvlazydg".
For example, If I were to key in. "abc" it would result as "the".
#include <stdio.h>
#include <string.h>
void encrypt(char *text, char *map);
void decrypt(char *text, char *map);
int main()
{
char a[] = {'a','b','c','d','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
char b[] = {'t','h','e','q','u','i','c','k','b','r','o','w','n','f','x','j','m','p','s','v','l','a','z','y','d','g'};
char *textptr;
char *mapptr;
textptr = a;
mapptr = b;
encrypt(textptr, mapptr);
return 0;
}
void encrypt(char *text, char *map)
{
char string[100];
int len;
int x = 0, y = 0, l = 1;
printf("Please enter the string: ");
scanf("%s", string);
len = strlen(string);
for (x = 0; x < len; x++)
{
for (y = 0; y < 26; y++)
{
if(text[x] == map[y])
text[x] = map[y];
}
}
printf("The Ciphertext is: %s", string);
}
and the output is the same plain text that was inputted.. can you guys help me on this?
Your problem lies here:
strcpy (string[q],map[r]);
You're passing two chars to strcpy() instead of char *. To replace a single character, just do
string[q] = map[r];
Edit: the new code
if(text[x] == map[y])
text[x] = map[y];
That obviously changes nothing. It should be
if( string[x] == text[y] )
string[x] = map[y];
This is the problem:
if(text[x] == map[y])
text[x] = map[y];
Use:
if(string[x] == text[y])
string[x] = map[y];
you can do this by using simply single for loop. and you need to define array a[].
for (x = 0; x < strlen(string); x++)
{
string[x]=map[string[x]-'a'];
}
Modified code:
#include <stdio.h>
#include <string.h>
#include<ctype.h>
void encrypt(char *map);
int main()
{
char b[] = {'t','h','e','q','u','i','c','k','b','r','o','w','n','f','x','j','m','p','s','v','l','a','z','y','d','g'};
char *mapptr;
mapptr = b;
encrypt(mapptr);
return 0;
}
void encrypt(char *map)
{
char string[100];
int x = 0;
printf("Please enter the string: ");
scanf("%s", string);
for (x = 0; x < strlen(string); x++)
{
if(islower(string[x]))
string[x]=map[string[x]-'a'];
}
printf("The Ciphertext is: %s\n", string);
}