在Ubuntu 14.04 64bit上进行md5加密编程

计算指定字符串的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

这样就可以方便地计算任意字符串的值了。参见如下截图

在Ubuntu 14.04 64bit上进行md5加密编程_第1张图片


二、使用OpenSSL中md5接口编程(使用MD5加密)

  我们以一个字符串为例,新建一个文件filename.txt,在文件内写入hello ,然后在Linux下可以使用命令md5sum filename.txt计算md5值 ==> b1946ac92492d2347c6235b4d2611184  。虽然写入的是hello这5个字符,但是我们使用命令xxd filename.txt后可以看出文件结尾处会有个0x0a这个回车符。所以在下面的代码中才会有\n。

在Ubuntu 14.04 64bit上进行md5加密编程_第2张图片



下面是提供的md5函数的接口

//打开/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.md5接口的调用有两套,一套是 MD5_Init,MD5_Update,MD5_Final,另一套是MD5,用哪一套都可以的。两种实现方式,一样的结果。相比较,第二种方法更直观简单些。
2.进行计算的类型分为字符串和本地文件,
3.在Ubuntu 14.04 64bit上需要链接 -lcrypto,在ContOS上需要链接,不论是保存为c文件还是cpp文件
4.临时缓存一定要使用unsigned char,不能使用char,因为unsigned char 0~255 ,char -127~127。使用char会出问题。这个md5加密函数,返回16个十进制数,范围在0~255间,把它format为十六进制就是32位md5编码了。
5.snprintf时的格式,%02X和%2.2格式是一样的,强制输出两位,比如十进制的8,十六进制也是8,这个格式是控制输出两位,08。如果加密结果要小写字母显示,就是"%2.2x",大写就是"2.2X"。
6.运行得到结果后,我们可以使用md5sum命令进行验证,并对比。
7.注意这里用到openssl库,并且限定在Ubuntu上, 如果在CentOS平台上,可以运行 yum install openssl  和 yum install openssl-devel 进行安装。

参考文献

[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

你可能感兴趣的:(MD5,OpenSSL)