将哈希输出作为 BYTE 而不是 std::string?
Hash output as BYTE instead of std::string?
我的 question/problem 可能是这个领域的新手,但我找不到任何解决方案或明确的解释来实现我想要的。
问题
由于大小的原因,我必须将散列值存储和使用为 BYTE 而不是 STRING。 (这给我带来了其他方面的麻烦)
该函数为文件生成 MD5 散列值,用于 windows OS。
当前代码
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,这对我来说是一个巨大的减少。
但是我不认为这是一个好的解决方案,我很确定必须有一种更简单、更清洁的方法来做到这一点。
非常感谢任何示例。
I must store and use the hash values as BYTE instead of STRING because of the size...
你快到了。
StringSource
和 ArraySink
都可以处理 byte
数组。您只需要使用替代构造函数。另请参阅 Crypto++ wiki 上的 StringSource
and ArraySink
。
我会修改类似下面的代码。我正在使用 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
中,这里是包裹 std::string
的源和汇。他们是不同的构造函数。
std::string digest;
...
StringSource(digest, ...);
StringSink(digest);
我的 question/problem 可能是这个领域的新手,但我找不到任何解决方案或明确的解释来实现我想要的。
问题
由于大小的原因,我必须将散列值存储和使用为 BYTE 而不是 STRING。 (这给我带来了其他方面的麻烦)
该函数为文件生成 MD5 散列值,用于 windows OS。
当前代码
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,这对我来说是一个巨大的减少。
但是我不认为这是一个好的解决方案,我很确定必须有一种更简单、更清洁的方法来做到这一点。
非常感谢任何示例。
I must store and use the hash values as BYTE instead of STRING because of the size...
你快到了。
StringSource
和 ArraySink
都可以处理 byte
数组。您只需要使用替代构造函数。另请参阅 Crypto++ wiki 上的 StringSource
and ArraySink
。
我会修改类似下面的代码。我正在使用 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
中,这里是包裹 std::string
的源和汇。他们是不同的构造函数。
std::string digest;
...
StringSource(digest, ...);
StringSink(digest);