提问人:Jabu 提问时间:10/26/2023 最后编辑:Jabu 更新时间:10/26/2023 访问量:111
如何使用 crypto++ 计算文件哈希
How to calculate file hash with crypto++
问:
我正在尝试将此哈希函数转换为“仅限 c++”并使用 crypto++ 库qt
QString calculateGitHubFileHash(const QString& filePath)
{
QFile file(filePath);
QString shaHash;
if( file.open(QFile::ReadOnly ) )
{
QCryptographicHash hash(QCryptographicHash::Sha1);
QByteArray header = QString("blob %1").arg(file.size()).toUtf8(); // Need to be null terminated
hash.addData(header.data(), header.size() + 1);
hash.addData(file.readAll());
shaHash = hash.result().toHex();
}
return shaHash;
}
一个可重现的工作示例:
#include <curl/curl.h>
#include <regex>
#include <fstream>
#include <cryptopp/sha.h>
#include <cryptopp/hex.h>
#include <cryptopp/filters.h>
static size_t WriteMemoryCallback(void* contents, size_t size, size_t nmemb, void* userp)
{
size_t realsize = size * nmemb;
auto& mem = *static_cast<std::string*>(userp);
mem.append(static_cast<char*>(contents), realsize);
return realsize;
}
void curl(std::string& data, const std::string& url)
{
CURL* curl_handle;
curl_handle = curl_easy_init();
curl_easy_setopt(curl_handle, CURLOPT_URL, url.data());
curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, &data);
curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "curl/7.55.1");
curl_easy_perform(curl_handle);
curl_easy_cleanup(curl_handle);
curl_global_cleanup();
}
std::string calculateGitHubFileHash(const std::string& filePath)
{
std::ifstream file(filePath, std::ios::binary);
std::string shaHash;
if (file.is_open())
{
// Get the size of the file
file.seekg(0, std::ios::end);
std::streamsize size = file.tellg();
file.seekg(0, std::ios::beg);
// Calculate the header
std::string header = "blob " + std::to_string(size);
// Read the file into a std::vector<byte>
std::vector<byte> fileContent(size);
file.read(reinterpret_cast<char*>(&fileContent[0]), size);
// Calculate the SHA1 hash
CryptoPP::SHA1 sha1;
CryptoPP::StringSource(
header + reinterpret_cast<const char*>(fileContent.data()),
true,
new CryptoPP::HashFilter(sha1, new CryptoPP::HexEncoder(new CryptoPP::StringSink(shaHash)))
);
}
return shaHash;
}
int main()
{
std::string json;
curl(json, "https://api.github.com/repos/jajabu33/test/contents");
// Using regex to parse the json to reduce code size, as this is just an reproducible example
std::regex nameRegex("\"name\":\\s*\"(.*?)\"");
std::regex shaRegex("\"sha\":\\s*\"(.*?)\"");
std::smatch nameMatches, shaMatches;
auto nIt = std::sregex_iterator(json.begin(), json.end(), nameRegex);
auto sIt = std::sregex_iterator(json.begin(), json.end(), shaRegex);
for (auto itName = nIt, itSha = sIt; itName != std::sregex_iterator() && itSha != std::sregex_iterator(); ++itName, ++itSha)
{
nameMatches = *itName;
shaMatches = *itSha;
std::string fileName = nameMatches[1];
std::string sha = shaMatches[1];
std::string localFileHash = calculateGitHubFileHash("C:/test.txt");
if (sha != localFileHash)
std::cout << "File " << fileName << " is not up to date\n";
}
}
在 GitHub 上,json 哈希正在使用它的本地副本上的函数生成相同的哈希值。test.txt
95d09f2b10159347eece71399a7e2e907ea3df4f
qt
test.txt
但是,用哈希值编写的是calculateGithubFileHash
crypto++
07C467E5526EEDE9510953A974DB07F3138AFA57
计算将 blob 标头追加到它的哈希值的正确方法是什么?
答: 暂无答案
评论
size
fileContent
CryptoPP::FileSource
blob n
blob
file
calculateGitHubFileHash(fileA)
calculateGitHubFileHash(fileB)
fileA
fileB
calculateGitHubFileHash(fileA)
QtVersion(fileA)
VectorSource