VC使用CryptoAPI计算MD5

// md5.h

#include <tchar.h>

#include <wincrypt.h>





// 计算Hash,成功返回0,失败返回GetLastError()

//  CONST BYTE *pbData,   // 输入数据 

//  DWORD dwDataLen,      // 输入数据字节长度 

//  ALG_ID algId          // Hash 算法:CALG_MD5,CALG_SHA

//  LPTSTR pszHash,       // 输出16进制Hash字符串,MD5长度为32+1, SHA长度为40+1

// 



DWORD GetHash(CONST BYTE *pbData, DWORD dwDataLen, ALG_ID algId, LPTSTR pszHash)

{

    DWORD dwReturn = 0;

    HCRYPTPROV hProv;

    if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))

        return (dwReturn = GetLastError());



    HCRYPTHASH hHash;

    //Alg Id:CALG_MD5,CALG_SHA

    if(!CryptCreateHash(hProv, algId, 0, 0, &hHash)) 

    {

        dwReturn = GetLastError();

        CryptReleaseContext(hProv, 0);

        return dwReturn;

    }



    if(!CryptHashData(hHash, pbData, dwDataLen, 0))

    {

        dwReturn = GetLastError();

        CryptDestroyHash(hHash);

        CryptReleaseContext(hProv, 0);

        return dwReturn;

    }



    DWORD dwSize;

    DWORD dwLen = sizeof(dwSize);

    CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)(&dwSize), &dwLen, 0);



    BYTE* pHash = new BYTE[dwSize];

    dwLen = dwSize;

    CryptGetHashParam(hHash, HP_HASHVAL, pHash, &dwLen, 0);



    lstrcpy(pszHash, _T(""));

    TCHAR szTemp[3];

    for (DWORD i = 0; i < dwLen; ++i)

    {

        //wsprintf(szTemp, _T("%X%X"), pHash[i] >> 4, pHash[i] & 0xf);

        wsprintf(szTemp, _T("%02X"), pHash[i]);

        lstrcat(pszHash, szTemp);

    }

    delete []pHash;



    CryptDestroyHash(hHash);

    CryptReleaseContext(hProv, 0);



    return dwReturn;

}



BOOL GetFileMd5(LPCTSTR lpFileName, LPTSTR pszHash)

{

    HANDLE hFile = CreateFile(lpFileName,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,NULL,NULL);

    if (hFile == INVALID_HANDLE_VALUE)     //如果CreateFile调用失败

    {

        //提示CreateFile调用失败,并输出错误号。visual studio中可在“工具”>“错误查找”中利用错误号得到错误信息。

        CloseHandle(hFile);

        return FALSE;

    }



    DWORD dwFileSize = GetFileSize(hFile,0);    //获取文件的大小

    if (dwFileSize == 0xFFFFFFFF)               //如果获取文件大小失败  

    {

        return FALSE;

    }



    BYTE* lpReadFileBuffer = new BYTE[dwFileSize];

    DWORD lpReadNumberOfBytes;

    if (ReadFile(hFile,lpReadFileBuffer,dwFileSize,&lpReadNumberOfBytes,NULL) == 0)  //读取文件  

    {

        return FALSE;

    }

    if (GetHash(lpReadFileBuffer, dwFileSize, CALG_MD5, pszHash))

    {

        return FALSE;

    }



    delete[]lpReadFileBuffer;

    CloseHandle(hFile);          //关闭文件句柄



    return TRUE;

}





BOOL GetStringMd5(TCHAR* pszStr, LPTSTR pszHash)

{

    if (GetHash((BYTE*)pszStr, _tcslen(pszStr), CALG_MD5, pszHash))

    {

        return FALSE;

    }



    return TRUE;

}
#include <windows.h>

#include "stdio.h"

#include "md5.h"

#include <locale.h>



int main()

{

    // 测试MD5

    TCHAR szMD5[41] = {0};

    setlocale(LC_ALL, "chs");



    // 测试字符串MD5

    TCHAR szStr[_MAX_FNAME] = _T("这是一段字符串");

    GetStringMd5(szStr, szMD5);

    wprintf(L"字符串: %s 的MD5值为: %s\n", szStr, szMD5);



    // 测试文件MD5

    TCHAR szFile[MAX_PATH] = _T("D:\\temp\\settings.db");

    GetFileMd5(szFile, szMD5);

    wprintf(L"文件: %s 的MD5值为: %s\n", szFile, szMD5);

}

 

你可能感兴趣的:(MD5)