#include "md5file.h" #include "md5global.h" #include "md5.h" #include #include #include #include #include std::string getFileMD5(const std::string& filename) { std::ifstream fin(filename.c_str(), std::ifstream::in | std::ifstream::binary); if (fin) { MD5_CTX context; MD5Init(&context); fin.seekg(0, fin.end); const auto fileLength = fin.tellg(); fin.seekg(0, fin.beg); const int bufferLen = 8192; std::unique_ptr buffer{ new unsigned char[bufferLen] {} }; unsigned long long totalReadCount = 0; decltype(fin.gcount()) readCount = 0; // 读取文件内容,调用MD5Update()更新MD5值 while (fin.read(reinterpret_cast(buffer.get()), bufferLen)) { readCount = fin.gcount(); totalReadCount += readCount; MD5Update(&context, buffer.get(), static_cast(readCount)); } // 处理最后一次读到的数据 readCount = fin.gcount(); if (readCount > 0) { totalReadCount += readCount; MD5Update(&context, buffer.get(), static_cast(readCount)); } fin.close(); // 数据完整性检查 if (totalReadCount != fileLength) { std::ostringstream oss; oss << "FATAL ERROR: read " << filename << " failed!" << std::ends; throw std::runtime_error(oss.str()); } unsigned char digest[16]; MD5Final(digest, &context); // 获取MD5 std::ostringstream oss; for (int i = 0; i < 16; ++i) { oss << std::hex << std::setw(2) << std::setfill('0') << static_cast(digest[i]); } oss << std::ends; return std::move(oss.str()); } else { std::ostringstream oss; oss << "FATAL ERROR: " << filename << " can't be opened" << std::ends; throw std::runtime_error(oss.str()); } }