哈希输出为 BYTE 而不是 std::string



我的问题/问题可能在这个领域有点新手,但我找不到任何解决方案或明确的解释来实现我想要的。

问题所在

由于大小的原因,我必须将哈希值存储和使用为 BYTE 而不是 STRING。(它给我带来了其他方面的麻烦(

该函数为在 Windows 操作系统上使用的文件生成 MD5 哈希。

当前代码

std::string MD5Checksum(const path &file)
{
    std::string result;
    try
    {
        CryptoPP::Weak::MD5 md5;
        CryptoPP::HashFilter f5(md5, new CryptoPP::HexEncoder(new CryptoPP::StringSink(result)));
        CryptoPP::ChannelSwitch cs;
        cs.AddDefaultRoute(f5);
        CryptoPP::FileSource ss(file.string().c_str(), true /*pumpAll*/, new CryptoPP::Redirector(cs));
    }
    catch (CryptoPP::Exception const& exception)
    {
      // 
    }
    return result;
}

我测试了什么

std::string MD5Checksum(const path &file)
{
    std::string result;
    try
    {
        CryptoPP::Weak::MD5 md5;
        CryptoPP::HashFilter f5(md5, new CryptoPP::HexEncoder(new CryptoPP::StringSink(result)));
        CryptoPP::ChannelSwitch cs;
        cs.AddDefaultRoute(f5);
        CryptoPP::FileSource ss(file.string().c_str(), true /*pumpAll*/, new CryptoPP::Redirector(cs));
    }
    catch (CryptoPP::Exception const& exception)
    {
        //
    }
    string decoded;
    CryptoPP::StringSource ss(result, true /*pumpAll*/, new CryptoPP::StringSink(decoded));
    const BYTE* data = reinterpret_cast<const BYTE*>(decoded.data());
    printf(L"sizeof result: %d, sizeof data: %d"), sizeof(result), sizeof(data));
    return result;
}

这似乎达到了预期的结果,因为结果字符串的大小为 40,数据的大小为 8,这对我来说是一个巨大的减少。

但是,我不认为这是一个好的解决方案,我很确定必须有一种更简单,更干净的方法来做到这一点。

任何例子都非常感谢。

由于大小,我必须将哈希值存储和使用为 BYTE 而不是字符串......

你快到了。

StringSourceArraySink 都可以处理byte数组。您只需要使用备用结构器。另请参阅Crypto++维基上的StringSourceArraySink

我将修改类似于以下内容的代码。我正在使用 C++11,所以我没有std::path

$ cat test.cxx
#include "cryptlib.h"
#include "filters.h"
#include "files.h"
#include "hex.h"
#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1
#include "md5.h"
#include <iostream>
#if defined(CRYPTOPP_NO_GLOBAL_BYTE)
using CryptoPP::byte;
#endif
bool MD5Checksum(const std::string &file, byte* digest, size_t size)
{
    using namespace CryptoPP;
    try
    {
        Weak::MD5 md5;
        FileSource(file.c_str(), true /*pumpAll*/,
            new HashFilter(md5, new ArraySink(digest, size)));
    }
    catch (Exception const& exception)
    {
        return false;
    }
    return true;
}
int main(int argc, char* argv[])
{
    using namespace CryptoPP;
    std::string filename = (argc >= 2 ? argv[1] : "./cryptlib.h");
    byte digest[Weak::MD5::DIGESTSIZE];
    if (MD5Checksum(filename, digest, sizeof(digest)))
    {
        std::cout << "Filename: " << filename << std::endl;
        std::cout << "Digest: ";
        StringSource(digest, sizeof(digest), true, new HexEncoder(new FileSink(std::cout)));
        std::cout << std::endl;
    }
    else
    {
        std::cerr << "Failed to calculate digest of " << filename << std::endl;
        std::exit(1);
    }
    return 0;
}

然后编译。我正在使用主目录中的cryptopp/目录:

$ g++ ./test.cxx ./libcryptopp.a -o test.exe
$

最后:

$ ./test.exe
Filename: ./cryptlib.h
Digest: 626047BC8770BE942B26B3AD6CBD3781

在上面的代码中,以下是包装字节数组的源和接收器:

StringSource(digest, sizeof(digest) ...);
ArraySink(digest, size);

如果您存储在std::string中,例如 如何轻松应用 Crypto++ 哈希函数?,这里是包装std::string的源和接收器。它们是不同的构造函数。

std::string digest;
...
StringSource(digest, ...);
StringSink(digest);

最新更新