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
", szStr, szMD5);

    // 测试文件MD5
    TCHAR szFile[MAX_PATH] = _T("D:\temp\settings.db");
    GetFileMd5(szFile, szMD5);
    wprintf(L"文件: %s 的MD5值为: %s
", szFile, szMD5);
}
原文地址:https://www.cnblogs.com/mumuli/p/4437618.html