Calculate Md5 of a String in C++

Calculate MD5 in C - Display output as string

You have it right, you just can't use printf("%s", digest); to print digest as a string. Note the unsigned char digest[16]; will be an array of unsigned char and will not be nul-terminated. You cannot print it as a string. Instead print each element as a hexadecimal number with 2 characters, e.g.

for (int i = 0; i < 16; i++)
printf("%02x", digest[i]);
putchar ('\n');

Your complete example would then be:

#include <stdio.h>
#include <string.h>
#include <openssl/md5.h>

void compute_md5(char *str, unsigned char digest[16]);

int main()
{
unsigned char digest[16];
compute_md5("hello world", digest);
for (int i = 0; i < 16; i++)
printf("%02x", digest[i]);
putchar ('\n');
return 0;
}

void compute_md5(char *str, unsigned char digest[16]) {
MD5_CTX ctx;
MD5_Init(&ctx);
MD5_Update(&ctx, str, strlen(str));
MD5_Final(digest, &ctx);
}

Example Use/Output

$ ./bin/md5openssl
5eb63bbbe01eeed093cb22bb8f5acdc3

Creating A String From digest

If you need to create a string from digest that you can print with printf ("%s\n", buf); then you create a buffer and instead of writing the 2-char hex representation to stdout, use sprintf to write it to a buffer, nul-terminate the buffer and then print the string. You could do:

int main()
{
unsigned char digest[16];
char buf[sizeof digest * 2 + 1];
compute_md5("hello world", digest);
for (int i = 0, j = 0; i < 16; i++, j+=2)
sprintf(buf+j, "%02x", digest[i]);
buf[sizeof digest * 2] = 0;
printf ("%s\n", buf);
return 0;
}

(output is the same)

Let me know if that isn't what you are looking for.

MD5 hashing in a string in C

Probably one of the biggest inconveniences of C is string handling. It's all very low level. char* is not simply a string that can be modified and written to however; it's just a pointer to memory.

There are several ways to correct the code, but here is my recommended fix:

// hashes two words and writes the digest to output.
void hashfunc(char* word1, char* word2, char* output) {
//concat both words
char concat[100];
strcpy(concat, word1);
strcat(concat, word2);

MD5_CTX md5;
MD5_Init(&md5);
MD5_Update(&md5,concat,strlen(concat));
MD5_Final(output,&md5);
}

Changes were:

  • Using a temporary work buffer to join the words together to be hashed.
  • Not returning a value, instead opting to let the user pass a buffer in to handle the return value.

Benefits of the second change is that the consumer can use memory on the stack rather than always being forced to deal with memory allocations inside of the function. (The other method would be to malloc memory and return that, which is slower and must be freed manually).

Also I'm not exactly sure how the MD5 library you're using works, but you can probably avoid the manual concatenation altogether:

void hashfunc(char* word1, char* word2, char* output) {
MD5_CTX md5;
MD5_Init(&md5);
MD5_Update(&md5,word1,strlen(word1));
MD5_Update(&md5,word2,strlen(word2));
MD5_Final(output,&md5);
}

And in case you need a usage example:

char ret[100];
hashfunc(a, b, ret);

How to create a md5 hash of a string in C?

I don't know this particular library, but I've used very similar calls. So this is my best guess:

unsigned char digest[16];
const char* string = "Hello World";
struct MD5Context context;
MD5Init(&context);
MD5Update(&context, string, strlen(string));
MD5Final(digest, &context);

This will give you back an integer representation of the hash. You can then turn this into a hex representation if you want to pass it around as a string.

char md5string[33];
for(int i = 0; i < 16; ++i)
sprintf(&md5string[i*2], "%02x", (unsigned int)digest[i]);

Calculate MD5 of a string in C++

You are passing a final newline to the md5sum program, but not to your code.

You can see that the bash <<< operator adds a newline:

$ od -ta <<<Hello
0000000 H e l l o nl
0000006

To avoid this, use printf:

$ printf '%s' Hello | od -ta
0000000 H e l l o
0000005
$ printf '%s' Hello | md5sum
8b1a9953c4611296a827abf8c47804d7 -

Alternatively, you could include a newline in your program version:

std::string str("Hello\n");

Calculate a MD5 hash from a string

As per MSDN

Create MD5:

public static string CreateMD5(string input)
{
// Use input string to calculate MD5 hash
using (System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create())
{
byte[] inputBytes = System.Text.Encoding.ASCII.GetBytes(input);
byte[] hashBytes = md5.ComputeHash(inputBytes);

return Convert.ToHexString(hashBytes); // .NET 5 +

// Convert the byte array to hexadecimal string prior to .NET 5
// StringBuilder sb = new System.Text.StringBuilder();
// for (int i = 0; i < hashBytes.Length; i++)
// {
// sb.Append(hashBytes[i].ToString("X2"));
// }
// return sb.ToString();
}
}

How Calculate MD5 and other hashes in C++?

For MD5 which is a 128-bit hash, you'd call it like this:

unsigned char* digest = nullptr;
unsigned int len = 0;

digest_message(message, message_len, &digest, &len);

Then to convert to 32-char hex string:

std::string s;
std::ostringstream ss;
for (unsigned int i = 0; i < len; i++)
{
ss << std::hex << std::setfill('0') << std::setwidth(2) << digest[i];
}
s = ss.str();

Don't forget to free the allocated hash after converting it:

OPENSSL_free(digest);

MD5 of string gives wrong output in C

Take a look at the output these two OpenSSL commands (which you can also replace with openssl dgst -md5 commands to get the same output):

$ md5 <(echo 12345)
MD5 (/dev/fd/63) = d577273ff885c3f84dadb8578bb41399
$ md5 <(printf 12345)
MD5 (/dev/fd/63) = 827ccb0eea8a706c4c34a16891f84e7b

The latter one is the one you are looking for. The difference between echo and printf is that the former adds a newline and the latter does not:

$ hexdump -C <(echo 12345)
00000000 31 32 33 34 35 0a |12345.|
00000006
$ hexdump -C <(printf 12345)
00000000 31 32 33 34 35 |12345|
00000005

So it is the 0a that is causing you the troubles.

Two additional remarks: the <(echo 12345) construct is an example of Process Substitution and instead of printf, you can also use echo -n. The latter is not standardized though, as pointed out in a comment below.

How to return the md5 hash in a string in this code C++?

replace

for (i=0;i<16;i++){
printf ("%02x", buffer_md5[i]);
result[i]=buffer_md5[i];
}

with

char buf[32];
for (i=0;i<16;i++){
sprintf(buf, "%02x", buffer_md5[i]);
result.append( buf );
}

notice that when you print out result, print result, not result[i] to get whole string.

if you put the buffer_md5[i] value directly in result then you may get problems since a string may not have an embedded 0 (if there is one).

Xcode C++ MD5 hash

You're using the wrong API. I'm not sure where you're getting those from (they look like OpenSSL calls), but it should look like this:

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

#include <CommonCrypto/CommonDigest.h>

int main()
{
unsigned char digest[CC_MD5_DIGEST_LENGTH];
const char string[] = "Hello World";

CC_MD5_CTX context;
CC_MD5_Init(&context);
CC_MD5_Update(&context, string, (CC_LONG)strlen(string));
CC_MD5_Final(digest, &context);

for (size_t i=0; i<CC_MD5_DIGEST_LENGTH; ++i)
printf("%.2x", digest[i]);
fputc('\n', stdout);
return 0;
}

Output

b10a8db164e0754105b7a99be72e3fe5

Validated here.



Related Topics



Leave a reply



Submit