zoukankan      html  css  js  c++  java
  • 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);
    }
  • 相关阅读:
    单据体内2个字段比较
    立账模式
    余额
    单据服务校验设置
    值更新事件(触发带基础属性到指定字段)
    重建索引 ,压缩数据库
    数据库自动备份
    BZOJ 4597: [Shoi2016]随机序列 线段树 + 思维
    BZOJ 4399: 魔法少女LJJ 线段树合并 + 对数
    BZOJ 2217: [Poi2011]Lollipop 构造 + 思维
  • 原文地址:https://www.cnblogs.com/mumuli/p/4437618.html
Copyright © 2011-2022 走看看