我用C语言写了一个简单的openssl示例,我想从我的消息中计算MD4散列,但我想将结果保存到一个字符数组中。下面是我的代码和注释,它将帮助您理解我想要实现的目标:
#include <string.h>
#include <openssl/md4.h>
#include <stdio.h>
int main()
{
unsigned char digest[MD4_DIGEST_LENGTH];
char string[] = "hello world";
// run md4 for my msg
MD4((unsigned char*)&string, strlen(string), (unsigned char*)&digest);
// save md4 result into char array - doesnt work
char test[MD4_DIGEST_LENGTH];
sprintf(test, "%02x", (unsigned int)digest);
for(int i = 0; i < MD4_DIGEST_LENGTH; i++)
printf("%02x", test[i]);
printf("\n\n");
// print out md4 result - works, but its not intochar array as I wanted it to be
for(int i = 0; i < MD4_DIGEST_LENGTH; i++)
printf("%02x", digest[i]);
printf("\n\n");
// works but i dont understand why 'mdString' is 33 size
char mdString[33];
for(int i = 0; i < MD4_DIGEST_LENGTH; i++)
// and I also dont get i*2 in this loop
sprintf(&mdString[i*2], "%02x", (unsigned int)digest[i]);
printf("md4 digest: %s\n", mdString);
return 0;
}问题是,为什么下面的代码不起作用,它显示的md4值不同于它应该显示的值:
char test[MD4_DIGEST_LENGTH];
sprintf(test, "%02x", (unsigned int)digest);
for(int i = 0; i < MD4_DIGEST_LENGTH; i++)
printf("%02x", test[i]);
printf("\n\n");我怎么知道mdString的大小应该是多少,为什么在最后一个循环中有i*2?有人能解释这个吗?
发布于 2013-07-14 02:34:44
首先,您对MD4()的调用为string和digest数组提供了错误的地址:通过使用&,您将获得数组的地址(char **),而不是第一个字符的地址。因为您显式地将&string和&digest强制转换为unsigned char*,所以编译器不会警告您。删除这些强制转换,您将收到以下警告:
warning: passing argument 1 of 'MD4' from incompatible pointer type
因此,请使用以下方式调用MD4():
MD4(string, strlen(string), digest);
我个人更喜欢避免显式地转换指针,除非真的有必要,这样你就更容易捕捉到不正确的类型转换。
接下来,尝试使用sprintf()将digest转换为十六进制整数:sprintf(test, "%02x", (unsigned int)digest);。这里有两件事是错误的:(a)由于digest本质上是一个字符指针,即:内存地址,您将这个地址转换为无符号整数,然后将该整数转换为十六进制;(b)您需要遍历digest的元素并将每个元素转换为字符,snprintf不会为您完成此操作!
我知道您可能对C语言比较陌生,但不要灰心,犯错才是学习的方法!:)
如果你买得起这本书,我强烈推荐Stephen Prata的"C Primer Plus“。对于任何刚开始编程的人来说,这是一本很好的入门书,也是一本非常完整的参考资料,可以在你已经熟悉这门语言的时候使用。另外,网上有很多资料,搜索"C指针教程“会返回几个有用的结果。
希望这能有所帮助!
编辑:
忘记注释另一段可以工作的代码,但使用33个字节来存储字符串化的MD4散列:
// works but i dont understand why 'mdString' is 33 size
char mdString[33];
for(int i = 0; i < MD4_DIGEST_LENGTH; i++)
// and I also dont get i*2 in this loop
sprintf(&mdString[i*2], "%02x", (unsigned int)digest[i]);
printf("md4 digest: %s\n", mdString);MD4() states的openssl手册页指出哈希值为16字节长。知道这一点,并且每个无符号字符可以包含从0到255的值,那么digest中任何单个元素的最大十六进制表示是0xFF,换句话说,每个无符号字符有2个ASCII字符。
msString (33)的大小看起来很神秘,因为MD4_DIGEST_LENGTH应该用来计算数组的大小:您需要2个字符来表示digest中的每个元素+1个空终止符('\0')来结束字符串:
char mdString[(MD4_DIGEST_LENGTH * 2) + 1];每当从mdString输入1个字节时,sprintf都会将2个字符输出到digest数组中,因此需要在mdString中为digest中的每个位置前进2个索引位置,因此使用了i * 2。以下命令会产生与使用i * 2相同的结果
for(int i = 0, j = 0; i < MD4_DIGEST_LENGTH; i++, j += 2)
sprintf(&mdString[j], "%02x", (unsigned int)digest[i]);https://stackoverflow.com/questions/17632485
复制相似问题