惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

J
Java Code Geeks
G
Google Developers Blog
Blog — PlanetScale
Blog — PlanetScale
U
Unit 42
A
About on SuperTechFans
Vercel News
Vercel News
B
Blog
Martin Fowler
Martin Fowler
MyScale Blog
MyScale Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
腾讯CDC
D
Docker
V
Visual Studio Blog
博客园 - 叶小钗
The Cloudflare Blog
Jina AI
Jina AI
B
Blog RSS Feed
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
WordPress大学
WordPress大学
T
Tailwind CSS Blog
MongoDB | Blog
MongoDB | Blog
D
DataBreaches.Net
月光博客
月光博客
大猫的无限游戏
大猫的无限游戏

博客园 - bodong

Unreal Engine 5创建项目失败:文件“{ConfigFile}”处理失败。 如何找到当前计算机所有的UnrealEngine安装位置 Unreal Engine 5调试资源依赖来源的方法 GhostDoc Enterprise.v2024.2.24300 for Visual Studio 2022插件漏洞分析和离线解锁方法 ScyllaHide插件可能导致x64dbg的日志窗口无法捕获应用程序输出的日志字符串 C++使用宏来判断当前编译期支持的C++标准版本的方法 VisualStudio各版本_MSC_VER和_MSC_FULL_VER宏定义值列表 Rider如何针对一个项目禁用某一类错误检查(Inspections)的办法 UnrealEngine 5 C++标准版本 UnrealEngine Setup即使挂了代理也很慢的解决办法 CPPStringFormatting: 使用.NET格式化字符串风格格式化C++字符串的库 Windows平台下使用C++检测硬盘分区是否属于SSD硬盘的方法 将C++代码文件路径、行号、函数名称等打包到#pragma message输出的方法 KnownDLLs列表 Avalonia实现Visual Studio风格标题栏的方法 解决IDA Pro Warning:mssdk64_win7: No such file or directory AHeadLib.Net C#版本的DLL劫持代码生成工具 安装Visual Studio 2022指定版本的方法 UnrealSharp: 一个可以让你在UnrealEngine5中采用C# 12和.NET 8.0开发的插件
Windows平台下使用C++和Windows API计算文件MD5的方法
bodong · 2024-05-30 · via 博客园 - bodong
#include <iostream>
#include <windows.h>
#include <tchar.h>
#include <string>
#include <cassert>
#include <functional>

typedef std::basic_string<TCHAR> StringT;
typedef std::string StringA;

#define _PP_CAT_IMPL_(a, b ) a ## b
#define PP_CAT(a, b) _PP_CAT_IMPL_( a, b )

namespace Details
{
    template <typename TCallable>
    class ScopedExit
    {
    public:
        ScopedExit(TCallable func) :
            Func(func)
        {
        }

        ~ScopedExit()
        {
            Func();
        }

        ScopedExit(const ScopedExit&) = delete;
        const ScopedExit& operator=(const ScopedExit&) = delete;

    private:
        TCallable Func;
    };
}

#define SCOPED_EXIT(expression) \
	::Details::ScopedExit<std::function<void()> > PP_CAT(ScopedExitInstalce_, __COUNTER__)([&]()\
{ \
	expression;\
})


StringA CalculateFileMD5(const StringT& filepath)
{
#define BUFSIZE 1024
#define MD5LEN  16

    DWORD dwStatus = 0;
    BOOL bResult = FALSE;
    HCRYPTPROV hProv = 0;
    HCRYPTHASH hHash = 0;
    HANDLE hFile = NULL;
    BYTE rgbFile[BUFSIZE];
    DWORD cbRead = 0;
    BYTE rgbHash[MD5LEN];
    DWORD cbHash = 0;
    CHAR rgbDigits[] = "0123456789abcdef";
    // Logic to check usage goes here.

    hFile = CreateFile(filepath.c_str(),
        GENERIC_READ,
        FILE_SHARE_READ,
        NULL,
        OPEN_EXISTING,
        FILE_FLAG_SEQUENTIAL_SCAN,
        NULL);

    if (INVALID_HANDLE_VALUE == hFile)
    {
        return "";
    }

    SCOPED_EXIT(CloseHandle(hFile));

    // Get handle to the crypto provider
    if (!CryptAcquireContext(&hProv,
        NULL,
        NULL,
        PROV_RSA_FULL,
        CRYPT_VERIFYCONTEXT))
    {
        return "";
    }

    SCOPED_EXIT(CryptReleaseContext(hProv, 0));

    if (!CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash))
    {
        return "";
    }

    SCOPED_EXIT(CryptDestroyHash(hHash));

    while (bResult = ReadFile(hFile, rgbFile, BUFSIZE, &cbRead, NULL))
    {
        if (0 == cbRead)
        {
            break;
        }

        if (!CryptHashData(hHash, rgbFile, cbRead, 0))
        {
            return "";
        }
    }

    if (!bResult)
    {
        return "";
    }

    cbHash = MD5LEN;
    if (CryptGetHashParam(hHash, HP_HASHVAL, rgbHash, &cbHash, 0))
    {
        StringA result;
        result.reserve(40);

        for (DWORD i = 0; i < cbHash; i++)
        {
            result.push_back(rgbDigits[rgbHash[i] >> 4]);
            result.push_back(rgbDigits[rgbHash[i] & 0xf]);
        }

        return result;
    }

    return "";
}

int main()
{
    auto md5 = CalculateFileMD5(_T("E:\\aow-install-apk-100.xml"));
    std::cout << md5 << std::endl;

    return 0;
}

  测试: