计算指定字符串的md5值是一项很常见的操作,包括使用命令行md5sum,或者在C/C++编程中调用openssl提供的接口函数来进行。下面我们分别阐述如下:
一、在命令行中使用md5校验
计算某个文件的md5校验值,通常就是在命令行输入md5sum就可以了
但是如果要方便地计算一个给出字符串的md5值,则md5sum就不合适了,因为md5sum只针对文件操作。为此我想到下面的变通方法:
在/usr/bin下面编写一个bash脚本
sudo vim md5
#!/bin/bash echo -n $1 | md5sum | awk '{print $1}'保存后,赋予可执行权限
sudo chmod +x md5
这样就可以方便地计算任意字符串的值了。参见如下截图
二、使用OpenSSL中md5接口编程(使用MD5加密)
我们以一个字符串为例,新建一个文件filename.txt,在文件内写入hello ,然后在Linux下可以使用命令md5sum filename.txt计算md5值 ==> b1946ac92492d2347c6235b4d2611184 。虽然写入的是hello这5个字符,但是我们使用命令xxd filename.txt后可以看出文件结尾处会有个0x0a这个回车符。所以在下面的代码中才会有\n。
//打开/usr/include/openssl/md5.h这个文件我们可以看到一些函数
// 初始化 MD5 Contex, 成功返回1,失败返回0
int MD5_Init(MD5_CTX *c);
// 循环调用此函数,可以将不同的数据加在一起计算MD5,成功返回1,失败返回0
int MD5_Update(MD5_CTX *c, const void *data, size_t len);
// 输出MD5结果数据,成功返回1,失败返回0
int MD5_Final(unsigned char *md, MD5_CTX *c);
// MD5_Init,MD5_Update,MD5_Final三个函数的组合,直接计算出MD5的值
unsigned char *MD5(const unsigned char *d, size_t n, unsigned char *md);
// 内部函数,不需要调用
void MD5_Transform(MD5_CTX *c, const unsigned char *b);
下面是分别针对字符串和本地文件的源码
str_md5_demo.c文件:
//gcc -g str_md5_demo.c -o str_md5_demo -lcrypto // #include <string.h> #include <stdio.h> #include <openssl/md5.h> int main(int argc, char* argv[]){ MD5_CTX ctx; unsigned char md[16] = {0}; int i = 0; //方法一: MD5_Init(&ctx); MD5_Update(&ctx, "hel", 3); MD5_Update(&ctx, "lo", 2); MD5_Final(md, &ctx); for (i = 0; i < 16; i++) printf("%02X", md[i]); printf("\n"); //方法二: const char data[] = "hello"; MD5(data, strlen(data), md); for (i = 0; i < 16; i++) printf("%02X", md[i]); printf("\n"); return 0; }file_md5_demo.c:
//gcc -g file_md5_demo.c -o file_md5_demo -lcrypto // #include <string.h> #include <stdio.h> #include <openssl/md5.h> int main(int argc, char* argv[]){ MD5_CTX ctx; unsigned char md[16] = {0}; char buffer[1024] = {0}; char filename[64] = {0}; int len = 0, i; FILE* fp = NULL; printf("请输入文件名, 用于计算MD5值\n"); scanf("%s", filename); fp = fopen(filename, "rb"); if(NULL == fp){ printf("can't open file\n"); return 1; } //方法一: MD5_Init(&ctx); while((len=fread(buffer, 1, sizeof(buffer), fp)) > 0){ MD5_Update(&ctx, buffer, len); memset(buffer, 0 ,sizeof(buffer)); } MD5_Final(md, &ctx); for(i=0; i<16; i++) printf("%02X", md[i]); printf("\n"); //方法二: while((len=fread(buffer, 1, sizeof(buffer), fp)) > 0){ MD5(buffer, len, md); memset(buffer, 0 ,sizeof(buffer)); } for(i=0; i<16; i++) printf("%02X", md[i]); printf("\n"); if(fp) fclose(fp); return 0; }
下面是运行效果截图, 同时给出了与md5或是md5check的对比图:
参考文献
[1].http://www.cnblogs.com/wunaozai/p/3887009.html
[2].http://www.cppblog.com/API/archive/2013/08/09/202427.html
[3].http://blog.webfuns.net/archives/1477.html