我有一个需要散列的大文件,但是如果我直接从文件中散列它,则我的内存将受到限制。我想散列2个步骤而不是1个步骤。例如,我首先使用算法CRC32
对文件进行哈希处理,然后存储在字符串中。然后执行第二步以再次哈希到SHA256
中。
目前,我成功完成了第一步的哈希文件。但是它会占用内存,如果内存不足,最终会返回错误或崩溃。
为了使在循环中使用cpu的程度不高。我决定选择1048576字节(1MB)作为块。在此测试中,我的控制台未返回crc32哈希。
CRC32 hash;
std::string str;
FileSource file("D:/1.exe", false, new HashFilter(hash, new HexEncoder(new StringSink(str))), true);
while (!file.SourceExhausted())
{
file.Pump(1048576);
}
std::cout << str;
getchar();
return 0;
答案 0 :(得分:0)
我有一个需要散列的大文件,但是如果我直接从文件中散列它,则我的内存将受到限制。所以我想分2步而不是1步哈希。例如我首先使用算法CRC32对文件进行散列并存储在字符串中。然后执行第二步以再次哈希到SHA256 ...
我认为您应该使用ChannelSwitch
并让库提供过滤器。默认情况下,该库使用4KB的块,它应使您保持在内存上限以下。
ChannelSwitch
可以将源数据馈送到多个过滤器,因此您只需读取一次数据。您不必担心编写自己的"tee"-like filter。
首先,修改程序以使用ChannelSwitch
并使用名为data.bin
的文件。您将在下面创建文件:
$ cat test.cxx
#include "cryptlib.h"
#include "channels.h"
#include "filters.h"
#include "files.h"
#include "sha.h"
#include "crc.h"
#include "hex.h"
#include <string>
#include <iostream>
int main(int argc, char* argv[])
{
using namespace CryptoPP;
try
{
std::string s1, s2;
CRC32 crc;
SHA1 sha1;
HashFilter f1(crc, new HexEncoder(new StringSink(s1)));
HashFilter f2(sha1, new HexEncoder(new StringSink(s2)));
ChannelSwitch cs;
cs.AddDefaultRoute(f1);
cs.AddDefaultRoute(f2);
FileSource("data.bin", true /*pumpAll*/, new Redirector(cs));
std::cout << "Filename: " << "data.bin" << std::endl;
std::cout << " CRC32: " << s1 << std::endl;
std::cout << " SHA1: " << s2 << std::endl;
}
catch(const Exception& ex)
{
std::cerr << ex.what() << std::endl;
}
return 0;
}
接下来,创建一个非常大的文件:
$ dd if=/dev/urandom of=data.bin bs=1M count=1024
1024+0 records in
1024+0 records out
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 5.48884 s, 196 MB/s
下一步,编译并运行程序:
$ g++ -g2 -O3 test.cxx ./libcryptopp.a -o test.exe
$
$ time ./test.exe
Filename: data.bin
CRC32: 20F45F3E
SHA1: F0857F8E46112BB08A04D5CE51BDBEA0C4539032
real 0m4.430s
user 0m4.269s
sys 0m0.156s
最后,如Pumping Data | Low Memory所述,使用Bash shell模拟内存不足的情况。注意,我们需要12 MB的空间来运行可执行文件。否则libc.so.6
会被链接加载程序映射失败。剩下大约4 MB的RAM用于程序和数据。
$ (ulimit -v 16368; ./test.exe)
Filename: data.bin
CRC32: 20F45F3E
SHA1: F0857F8E46112BB08A04D5CE51BDBEA0C4539032