Will MD5( libcrypto ) work on string which contain null in between? - c

I have two strings as below
Str1: 1234\099
Str2: 123499
If I calculate MD5 on these string using unsigned char *MD5(const unsigned char *d, unsigned long n, unsigned char *md);
Will the function MD5 calculate the hash for first 4 bytes of Str1 or would it take the complete string "1234\099".
Will the MD5 of Str1 and Str2 be same or different????
Thanks

That all depends on what value you pass for the n parameter.
If you use strlen() to calculate n, then the MD5() function will process data up to, but not including, the null (because you told it to, in effect).
If you pass in the correct length for n (I assume that's 7 for Str1), then MD5() will include all the data in the hash, including null bytes and data past the null.
The hash for Str1 and Str2 will be different (assuming you pass in something larger than 3 for n).

const unsigned char *d it's firs element of array, not C-style string.
So specify proper length (7 elements) of (const unsigned char *)"1234\099" you will obtain its MD5 into md.

Yes, Michael is right. I executed the below program and it seems that MD5 calculation takes place on second argument irrespective of what is in the string.
#include <stdio.h>
#include <openssl/md5.h>
int main() { <br>
char *p = NULL;<br>
char *c = NULL;<br>
char *q = NULL;<br>
p = malloc(10*(sizeof(char)));
strncpy(p, "ABCDEDFGO", 9);
c = malloc(200*(sizeof(char)));
memset(c,0, 200);
p[3] = '\0';
q = MD5(p, 9, c);
printf("\n For 9 bytes hash %x", *c);
q = MD5(p, 4, c);
printf("\n For 4 bytes hash %x", *c);
q = MD5(p, 3, c);
printf("\n For 3 bytes hash %x", *c);
free(c);
return (0);
}
For 9 bytes hash ffffffc9
For 4 bytes hash ffffffe5
For 3 bytes hash ffffff90

Related

Function is returning a different value every time?

I'm trying to convert a hexadecimal INT to a char so I could convert it into a binary to count the number of ones in it. Here's my function to convert it into char:
#include <stdio.h>
#include <stdlib.h>
#define shift(a) a=a<<5
#define parity_even(a) a = a+0x11
#define add_msb(a) a = a + 8000
void count_ones(int hex){
char *s = malloc(2);
sprintf(s, "0x%x", hex);
free(s);
printf("%x", s);
};
int main() {
int a = 0x01B9;
shift(a);
parity_even(a);
count_ones(a);
return 0;
}
Every time I run this, i always get different outputs but the first three hex number are always the same. Example of outputs:
8c0ba2a0
fc3b92a0
4500a2a0
d27e82a0
c15d62a0
What exactly is happening here? I allocated 2 bytes for the char since my hex int is 2 bytes.
It's too long to write a comment so here goes:
I'm trying to convert a hexadecimal INT
int are stored as a group of value, padding (possible empty) and sign bits, so is there no such thing as a hexadecimal INT but you can represent (print) a given number in the hexadecimal format.
convert a ... INT to a char
That would be lossy conversion as an int might have 4 bytes of data that you are trying to cram into a 1 byte. char specifically may be signed or unsigned. You probably mean string (generic term) or char [] (standard way to represent a string in C).
binary to count the number of ones
That's the real issue you are trying to solve and this is a duplicate of:
How to count the number of set bits in a 32-bit integer?
count number of ones in a given integer using only << >> + | & ^ ~ ! =
To address the question you ask:
Need to allocate more than 2 bytes. Specifically ceil(log16(hex)) + 2 (for 0x) + 1 (for trailing '\0').
One way to get the size is to just ask snprintf(s, 0, ...)
then allocate a suitable array via malloc (see first implementation below) or use stack allocated variable length array (VLA).
You can use INT_MAX instead of hex to get an upper
bound. log16(INT_MAX) <= CHAR_BIT * sizeof(int) / 4 and the
latter is a compile time constant. This means you can allocate your string on stack (see 2nd implementation below).
It's undefined behavior to use a variable after it's deallocated. Move free() to after the last use.
Here is one of the dynamic versions mentioned above:
void count_ones(unsigned hex) {
char *s = NULL;
size_t n = snprintf(s, 0, "0x%x", hex) + 1;
s = malloc(n);
if(!s) return; // memory could not be allocated
snprintf(s, n, "0x%x", hex);
printf("%s (size = %zu)", s, n);
free(s);
};
Note, I initialized s to NULL which would cause the first call to snprintf() to return an undefined value on SUSv2 (legacy). It's well defined on c99 and later. The output is:
0x3731 (size = 7)
And the compile-time version using a fixed upper bound:
#include <limits.h>
// compile-time
void count_ones(unsigned hex) {
char s[BIT_CHAR * sizeof(int) / 4 + 3];
sprintf(s, "0x%x", hex);
printf("%s (size = %zu)", s, n);
};
and the output is:
0x3731 (size = 11)
Your biggest problem is that malloc isn't allocating enough. As Barmar said, you need at least 7 bytes to store it or you could calculate the amount needed. Another problem is that you are freeing it and then using it. It is only one line after the free that you use it again, which shouldn't have anything bad happen like 99.9% of the time, but you should always free after you know you are done using it.

Cast an int array to string, then print with printf, without allocating new memory

I thought I had this solved, but apparently, I was incorrect. The question is... what did I miss?
Assignment description:
You are to create a C program which fills an integer array with integers and then you are to cast it as a string and print it out. The output of the string should be your first and last name with proper capitalization, spacing and punctuation. Your program should have structure similar to:
main()
{
int A[100];
char *S;
A[0]=XXXX;
A[1]=YYYY;
...
A[n]=0; -- because C strings are terminated with NULL
...
printf("My name is %s\n",S);
}
Response to my submission:
You still copied memory cells to other, which is not expected. You use different space for the integer array as the string which does not follow the requirements. Please follow the instructions carefully next time.
My submission
Note that the first time I submitted, I simply used malloc on S, and copied casted values from A to S. The response was that I could not use malloc or allocate new space. This requirement was not in the problem description above.
Below was my second and final submission, which is the submission being referred to in the submission response above.
#include <stdio.h>
/* Main Program*/
int main (int arga, char **argb){
int A[100];
char *S;
A[0] = 68;
A[1] = 117;
/** etc. etc. etc. **/
A[13] = 115;
A[14] = 0;
// Point a char pointer to the first integer
S = (char *) A;
// For generality, in C, [charSize == 1 <= intSize]
// This is the ratio of intSize over charSize
int ratio = sizeof(int);
// Copy the i'th (char sized) set of bytes into
// consecutive locations in memory.
int i = 0;
// Using the char pointer as our reference, each set of
// bits is then i*ratio positions away from the i'th
// consecutive position in which it belongs for a string.
while (S[i*ratio] != 0){
S[i] = S[i*ratio];
i++;
}
// a sentinel for the 'S string'
S[i] = 0;
printf("My name is %s\n", S);
return 0;
}// end main
It looks like you've got the core idea down: the space for one integer will hold many chars. I believe you just need to pack the integer array "by hand" instead of in the for loop. Assuming a 4-byte integer on a little-endian machine, give this a shot.
#include <stdio.h>
int main()
{
int x[50];
x[0] = 'D' | 'u' << 8 | 's' << 16 | 't' << 24;
x[1] = 0;
char *s = (char*)x;
printf("Name: %s\n", s);
return 0;
}
It sounds like your professor wanted you to put 4 bytes into each int instead of having an array of n "1 byte" ints that you later condensed into 4 / sizeof(int) bytes using the while loop. Per Hurkyl's comment, the solution to this assignment would be platform dependent, meaning that it will differ from machine to machine. I'm assuming your instructor had the class ssh into and use a specific machine?
In any case, assuming you're on a little endian machine, say you wanted to type out the string: "Hi Dad!". Then a snippet of the solution would look something like this:
// Precursor stuff
A[0] = 0x44206948; // Hi D
A[1] = 0x216461; // ad!
A[2] = 0; // Null terminated
char *S = (char *)A;
printf("My string: %s\n", S);
// Other stuff

Byte allocation in short unsigned data

kindly check the following program
#include <stdio.h>
#include<stdlib.h>
int main()
{
char *Date= NULL;
unsigned short y=2013;
Date = malloc(3);
sprintf((char *)Date,"%hu",y);
printf("%d %d %d %d %d \n",Date[0],Date[1],Date[2],Date[3],Date[4]);
printf("%s %d %d",Date,strlen(Date),sizeof(y));
}
output:
50 48 49 51 0
2013 4 2
How I am getting the string length 4 instead 2,as I am putting a short integer value into the memory so it should be occupied in 2 byte of memory.But how it is taking 4 byte.
How each byte getting 2 0 1 3 from the input, instead 20 in one byte and 13 in another byte.
I want to put 20 to one byte and 13 to another byte.How to do that.kindly tell something
Kindly give some answer.
As indicate by its name, the sprintf function write a formated string. So, your number 2013 is converted to "2013" (a 5 character string).
You are invoking undefined behaviour.
You have allocated only 3 bytes for Date and storing 5 bytes.
Four bytes for 2013 and 1 NUL byte. So you should allocate at least 5 bytes if you want to store 2013.
If you want to transfer a stream of bytes then I suggest you do in the following way:
#include <stdio.h>
#include<string.h>
#include<stdlib.h>
int main()
{
unsigned char *Date= NULL;
unsigned short y=2013;
unsigned char *p;
p = (unsigned char*) &y;
Date = malloc(3);
Date[0] = *p;
Date[1] = *(p+1);
Date[2] = 0;
printf("%s %d %d",Date,strlen(Date),sizeof(y));
}
This outputs:
� 2 2
The strange char is because interpreting some byte values as a string. Plain char may be signed or unsigned depending on your implementation. So use unsigned char to avoid incorrect interpretation of bytes.

Simple int to char[] conversion

I have a simple question
How to simply convert integer (getting values 0-8) to char, e.g. char[2] in C?
Thanks
main()
{
int i = 247593;
char str[10];
sprintf(str, "%d", i);
// Now str contains the integer as characters
}
Hope it will be helpful to you.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void main()
{
int a = 543210 ;
char arr[10] ="" ;
itoa(a,arr,10) ; // itoa() is a function of stdlib.h file that convert integer
// int to array itoa( integer, targated array, base u want to
//convert like decimal have 10
for( int i= 0 ; i < strlen(arr); i++) // strlen() function in string file thar return string length
printf("%c",arr[i]);
}
Use this. Beware of i's larger than 9, as these will require a char array with more than 2 elements to avoid a buffer overrun.
char c[2];
int i=1;
sprintf(c, "%d", i);
If you want to convert an int which is in the range 0-9 to a char, you may usually write something like this:
int x;
char c = '0' + x;
Now, if you want a character string, just add a terminating '\0' char:
char s[] = {'0' + x, '\0'};
Note that:
You must be sure that the int is in the 0-9 range, otherwise it will fail,
It works only if character codes for digits are consecutive. This is true in the vast majority of systems, that are ASCII-based, but this is not guaranteed to be true in all cases.
You can't truly do it in "standard" C, because the size of an int and of a char aren't fixed. Let's say you are using a compiler under Windows or Linux on an intel PC...
int i = 5;
char a = ((char*)&i)[0];
char b = ((char*)&i)[1];
Remember of endianness of your machine! And that int are "normally" 32 bits, so 4 chars!
But you probably meant "i want to stringify a number", so ignore this response :-)

How to get the binary presentation in hex value of a char

Given a char, how to convert this char to a two digit char, which is the hex value of the binary presentation?
For example, given a char, it has a binary presentation, which is one byte, for example, 01010100, which is 0x54.....I need the char array of 54.
Actually it would be:
char c = 84;
char result[3];
sprintf(result,"%02x",c);
This is all far to easy readable :-)
#define H(x) '0' + (x) + ((x)>9) * 7
char c = 84;
char result[3] = { H(c>>4), H(c&15) };
The following code, using snprintf() should work:
#include <stdio.h>
#include <string.h>
int main()
{
char myChar = 'A'; // A = 0x41 = 65
char myHex[3];
snprintf(myHex, 2 "%02x", myChar);
// Print the contents of myHex
printf("myHex = %s\n", myHex);
}
snprintf() is a function that works like printf(), except that it fills a char array with maximum N characters. The syntax of snprintf() is:
int snprintf(char *str, size_t size, const char *format, ...)
Where str is the string to "sprint" to, size is the maximum number of characters to write (in our case, 2), and the rest is like the normal printf()

Resources