MD5校驗

(一)來自:http://www.cnblogs.com/zhenjing/p/openssl.html

OpenSSL http://www.openssl.org/ OpenSSL整個軟件包大概可以分成三個主要的功能部分:密碼算法庫、SSL協議庫以及應用程序。OpenSSL 的密碼算法庫包含多種加密算法的實現,可單獨應用。

OpenSSL 下載:http://www.openssl.org/source/

安裝:

./config --prefix=/data/chenzhenjing/local

make (若編譯不過,make clean後重試)

make install 

一個利用OpenSSL MD5算法的簡單示例程序:功能:根據文本文件的地一個非空字符串進行hash


/*
 * =====================================================================================
 *
 *       Filename:  SplitProduct.c
 *
 *    Description:  
 *
 *        Version:  1.0
 *        Created:  04/03/2013 04:49:06 PM CST
 *       Revision:  none
 *       Compiler:  
 *                  gcc -std=c99 -I/data/chenzhenjing/local/include/openssl/ -c SplitProduct_md5.c
 *                  gcc -std=c99 -o  test_md5 SplitProduct_md5.o  /data/chenzhenjing/local/lib/libcrypto.a
 *
 *         Author:  Zhenjing Chen (zhenjing), [email protected]
 *        Company:  
 *
 * =====================================================================================
 */

#define _GNU_SOURCE
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <ctype.h>
#include "openssl/md5.h"

MD5_CTX  md5_ctx;

static int MD5mod(const char* str, int length, int mod){
    char sign[16] = {0};
    
    MD5_Init(&md5_ctx);
    MD5_Update(&md5_ctx, str, length);
    MD5_Final(sign, &md5_ctx);

    int sum = 0;
    for (int i=0; i < 16; i ++) {
        sum += (sign[i]&0xff);
    }
    int offset = sum % mod;
    return offset;
}

int main(int argc, char** argv)
{
    if( argc < 4){
        fprintf(stderr, "%s num infile outfile\n", argv[0]);
        exit(-1);
    }
    int num = atoi(argv[1]) ;
    if( num <= 0){
        fprintf(stderr, "ERROR: num error: %s\n", argv[1]);
        exit(-1);
    }

    FILE* in = fopen(argv[2], "r");
    if( in == NULL){
        perror("fopen");
        fprintf(stderr, "ERROR: infile error: %s\n", argv[2]);
        exit(-1);
    }

    FILE** OUT = (FILE**)malloc(sizeof(FILE*) * num);
    for(int i=0; i<num; ++i){
        char buf[256] = {0};
        sprintf(buf, "%s_%d", argv[3], i);
        OUT[i] = fopen(buf, "w");
        if( OUT[i] == NULL){
            perror("fopen");
            fprintf(stderr, "ERROR: infile error: %s\n", argv[2]);
            exit(-1);
        }
    }

    size_t len = 0;
    ssize_t read;
    char * line = NULL;

    while ((read = getline(&line, &len, in)) != -1) {
        int  klen = 0;
        while( klen < read ){
            if( isspace( *(line+klen)) ) break;

            klen++;
        }

     //   char id[256]={0};
     //   strncpy(id, line, klen);
     //   printf("id=%s\tklen=%d\tread=%ld\tline=%s", id, klen, read, line);

        fprintf(OUT[MD5mod(line, klen, num)], "%s", line);
    }

    if(line) free(line);

    return 0;
}


(二)來自:http://blog.csdn.net/dgyanyong/article/details/21415961

在linux機器上,有一個命令可以計算出文件的md5值,那就是md5sum,如果沒有的話,就需要安裝RPM包:coreutils。

現在我們使用openssl的庫也可以方便的計算出文件的md5值。主要用到的函數是

int MD5_Init(MD5_CTX *c);
int MD5_Update(MD5_CTX *c, const void *data, size_t len);
int MD5_Final(unsigned char *md, MD5_CTX *c);

使用庫前,先需要安裝openssl的RPM包。這三個函數不需要解釋,看下面一個例子就知道:

  1. #include <openssl/md5.h>  
  2. #include <iostream>  
  3. #include <cstdio>  
  4. #include <iomanip>  
  5. using namespace std;  
  6.   
  7.   
  8. int main()  
  9. {  
  10.         FILE *fd=fopen("test","r");  
  11.         MD5_CTX c;  
  12.         unsigned char md5[17]={0};  
  13.         if(fd == NULL)  
  14.         {  
  15.                 cout << "open failed" << endl;  
  16.                 return -1;  
  17.         }  
  18.         int len;  
  19.         unsigned char *pData = (unsigned char*)malloc(1024*1024*1024);  
  20.         if(!pData)  
  21.         {  
  22.                 cout << "malloc failed" << endl;  
  23.                 return -1;  
  24.         }  
  25.         MD5_Init(&c);  
  26.         while( 0 != (len = fread(pData, 1, 1024*1024*1024, fd) ) )  
  27.         {  
  28.                 MD5_Update(&c, pData, len);  
  29.         }  
  30.         MD5_Final(md5,&c);  
  31.         for(int i = 0; i < 16; i++)  
  32.                 cout << hex << setw(2) << setfill('0') << (int)md5[i];  
  33.         cout << endl;  
  34.         fclose(fd);  
  35.         free(pData);  
  36.         return 0;  
  37. }  



編譯鏈接選項爲:

g++ test.cpp -o testmd5 -lcrypto -lssl

生成testmd5後,我們把一個300多M的test文件放到與testmd5一個目錄。並把testmd5生成的結果和linux命令"md5sum test" 結果對比,會發現是一樣的。

  1. int GetFileMD5(std::string strFile, std::string& strMD5)  
  2. {  
  3.     int nLen = 0;  
  4.     unsigned int nBufferSize = 1024 * 1024;  
  5.     char szTemp[4];  
  6.     unsigned char szMD5[20];  
  7.     MD5_CTX ctx;  
  8.       
  9.     // set buffer size by file size  
  10.     ACE_stat stFileInfo;  
  11.     memset(&stFileInfo, 0, sizeof(ACE_stat));  
  12.     nRet = ACE_OS::lstat(strFile.c_str(), &stFileInfo);  
  13.     if (nRet != 0)  
  14.     {  
  15.         printf("stat file error[%s].\n", strFile.c_str());  
  16.         return -1;  
  17.     }  
  18.     if (stFileInfo.st_size < nBufferSize)  
  19.     {  
  20.         nBufferSize = stFileInfo.st_size + 64;  
  21.     }  
  22.     // open file  
  23.     FILE *fp = fopen(strFile.c_str(), "r");  
  24.     if(fd == NULL)  
  25.     {  
  26.         printf("fopen error:%s.\n", strFile.c_str());  
  27.         return -1;  
  28.     }  
  29.     unsigned char *pDataBuffer = (unsigned char*)malloc(nBufferSize);  
  30.     if(NULL == pDataBuffer)  
  31.     {  
  32.         printf("malloc error:%d.\n", nBufferSize);  
  33.         fclose(fp)  
  34.         return -1;  
  35.     }  
  36.     // get md5  
  37.     MD5_Init(&ctx);  
  38.     while(true)  
  39.     {  
  40.         memset(pDataBuffer, 0, nBufferSize);  
  41.         nLen = fread(pDataBuffer, 1, nBufferSize, fp);  
  42.         if(nLen == 0)  
  43.         {  
  44.             break;  
  45.         }  
  46.         MD5_Update(&ctx, pDataBuffer, nLen);  
  47.     }  
  48.     MD5_Final(szMD5, &ctx);  
  49.     // md5 to string  
  50.     strMD5 = "";  
  51.     for(int i = 0; i < 16; i++)  
  52.     {  
  53.         memset(szTemp, 0, sizeof(szTemp));  
  54.         snprintf(szTemp, sizeof(szTemp), "%02x", (int)szMD5[i]);  
  55.         strMD5 += szTemp;  
  56.     }  
  57.     fclose(fp);  
  58.     if(NULL != pDataBuffer)  
  59.     {  
  60.         free(pDataBuffer);  
  61.         pDataBuffer = NULL;  
  62.     }  
  63.     return 0;  
  64. }  




發佈了90 篇原創文章 · 獲贊 17 · 訪問量 19萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章