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);
}
时间: 2024-08-24 13:14:52

VC使用CryptoAPI计算MD5的相关文章

c# 如何给文件计算MD5

在项目中,当我们需要把数据文件上传到ftp时,为了保证数据的完整性,我们会计算数据文件的MD5,并把MD5文件和数据文件一同上传. 那么如何产生数据文件的MD5呢? 我们可以通过System.Security.Cryptography.MD5类和System.BitConverter类来实现: private void WriteMD5(string zipFile, string ctrlFile)        {            // Add hash code to ctrl fi

最简单的计算MD5方法

原来写过一个计算MD5的程序,是用了一个叫MD5.pas的单元,使用起来还算简单,但还有更简单的办法,安装了indy就会有IdHashMessageDigest单元(delphi 7默认安装indy) 有篇文章教怎么用IdHashMessageDigest计算字符串md5,计算文件md5却没有说,在这里补充一下,先看计算函数: function TIdHashMessageDigest4.HashValue(AStream: TStream): T4x4LongWordRecord;参数类型是一

node快速计算md5

最近在做一个文件上传的项目,当上传文件达到几十GB,几百GB后在文件上传99%后,需要等待非常长的时间文件才能完成上传.通过埋点打印时间,发现md5计算时间非常长. 为了校验文件传输的完整性需要在文件上传结束后校验文件的完整性,md5值就用来校验完整性,所以这一步不能少. 解决方案 通过网上查找资料,MD5计算工具在计算大文件md5值时也不是一次性计算出来的,也是通过分片的方式累加计算出来的. 所以我们在上传大文件时,本来上传的思路就是分片上传,我们只需要对每块分片进行md5计算,最后累加计算m

计算 MD5值

// // MD5Value.h // iOSEdu // // Created by littest on 16/2/26. // Copyright © 2016年 littest. All rights reserved. // #import <Foundation/Foundation.h> #import <CommonCrypto/CommonDigest.h> #define FileHashDefaultChunkSizeForReadingData 1024*8

java实现计算MD5

import java.io.FileInputStream; import java.security.DigestInputStream; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; public class MD5Class { // 计算字符串的MD5 public static String conVertTextToMD5(String plainText) {

Java常用工具类(计算MD5,验证码随机生成,天数差值计算)

写这个博文的目的是为了怕哪天自己的电脑崩溃了,以前写的那些代码就没了,所以将自己写的工具类贴出来,方便以后去使用,也避免自己反复去创造轮子, 也可以对这些方法进行简单修改来完成业务需求,这样就可以极大的提高开发的效率. 方法一:计算字符串的MD5的值 使用方法很简单,直接把值传入方法中就可以了,会返回一个字符串String注意去获取. public final static String calculateMD5(String s) { char hexDigits[] = { '0', '1'

python 计算md5

import hashlib src = "afnjanflkas" m2 = hashlib.md5() m2.update(src) print m2.hexdigest() --------> 输出的值 md5值

Python两种方法计算MD5值

1.Python内置md5模块 1 #-*- coding:utf-8 -*- 2 3 import md5 4 5 def Str2Md5(s): 6 m=md5.new() 7 m.update(s) 8 return m.hexdigest() 9 10 if __name__=="__main__": 11 s="www.baidu.com" 12 print Str2Md5(s) 2.Python的hashlib模块 1 #-*- coding:utf-8

在VMW 虚拟桌面环境下 VC总是提示 计算虚拟磁盘空间

最近迁移了VC之后 在VC中出现了以下提示,而且很频繁 同事之前说是克隆链接的问题,但是克隆链接的桌面池已经全部干掉了,还是会出现在这个提示. 客户这边说这个提示很麻烦,希望去掉. 登录View administrator后 在左侧的View配置-服务器中 右边选中当前的VC-编辑 把启动View STorage Accelerator的勾取消就好 主机缓存问题. 关于这个功能,官方给出的解释是这样的: 在 vSphere 5.0 及更高版本中,您可以将 ESXi 主机配置为缓存虚拟机磁盘数据.