2020-06-13 17:21:23 +08:00

70 lines
1.7 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "md5file.h"
#include "md5.h"
#include <fstream>
#include <sstream>
#include <memory>
#include <iomanip>
#include <exception>
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<unsigned char[]> buffer{ new unsigned char[bufferLen] {} };
unsigned long long totalReadCount = 0;
decltype(fin.gcount()) readCount = 0;
// 读取文件内容调用MD5Update()更新MD5值
while (fin.read(reinterpret_cast<char*>(buffer.get()), bufferLen))
{
readCount = fin.gcount();
totalReadCount += readCount;
MD5Update(&context, buffer.get(), static_cast<unsigned int>(readCount));
}
// 处理最后一次读到的数据
readCount = fin.gcount();
if (readCount > 0)
{
totalReadCount += readCount;
MD5Update(&context, buffer.get(), static_cast<unsigned int>(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<unsigned int>(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());
}
}