【发布时间】:2011-11-01 20:08:19
【问题描述】:
我有一个目前仅使用 SHA1 对文件进行哈希处理的程序。没有其他选择。它使用 Lazarus 和 Free Pascal 编译器中的 SHA1 哈希函数对它们进行哈希处理。
此后,我通过使用 DCPCrypt 库(http://wiki.lazarus.freepascal.org/DCPcrypt 或 http://www.cityinthesky.co.uk/opensource)添加了使用 MD5、SHA256 和 SHA512 的功能。一切正常,但是,如果文件大于 1Mb,我的早期版本会将文件散列在 2Mb 缓冲区中。如果小于 1Mb,则使用 1024 字节的默认缓冲区,如下所示:
if SizeOfFile > 1048576 then // if > 1Mb
begin
fileHashValue := SHA1Print(SHA1File(NameOfFileToHash, 2097152)); //2Mb buffer
end
else
fileHashValue := SHA1Print(SHA1File(NameOfFileToHash)); //1024 byte buffer
但是,我的散列函数和过程现在已移至由单选按钮状态控制的单个函数,以使我的代码更加面向对象。它基本上在其中编码了所有 4 个散列选项,运行哪个部分取决于程序找到的 RadioButton.Checked 状态。例如,SHA1 的代码现在看起来像这样:
..
SourceData := TFileStream.Create(FileToBeHashed, fmOpenRead);
..
else if SHA1RadioButton2.Checked = true then
begin
varSHA1Hash := TDCP_SHA1.Create(nil);
varSHA1Hash.Init;
varSHA1Hash.UpdateStream(SourceData, SourceData.Size); // HOW DO I ADD A BUFFER HERE?
varSHA1Hash.Final(DigestSHA1);
varSHA1Hash.Free;
for i := 0 to 19 do // 40 character output
GeneratedHash := GeneratedHash + IntToHex(DigestSHA1[i],2);
end // End of SHA1 if
我的问题是,如果找到的文件“大”(例如,大于 1Mb),如何向 varSHA1Hash.UpdateStream 添加缓冲区大小?这很重要,因为例如一个 300Mb 的文件,我的早期版本需要 4 秒,而现在使用 DCPCrypt 库的“改进”版本需要 9 秒!因此,即使我的代码读起来更好,它也将大文件所需的时间增加了一倍。如果我可以让 varSHA1Hash.UpdateStream 一次读取几 Mb 的数据,而不是 8k 字节缓冲区(如果您阅读代码库,UpdateStream 过程会这样做),它将使其更快。就目前而言,我的理解是 varSHA1Hash.UpdateStream(SourceData, SourceData.Size);基本上是读取正在读取的文件的整个大小作为缓冲区?
如果有帮助,这里是来自
的 UpdateStream 过程procedure TDCP_hash.UpdateStream(Stream: TStream; Size: longword);
var
Buffer: array[0..8191] of byte;
i, read: integer;
begin
dcpFillChar(Buffer, SizeOf(Buffer), 0);
for i:= 1 to (Size div Sizeof(Buffer)) do
begin
read:= Stream.Read(Buffer,Sizeof(Buffer));
Update(Buffer,read);
end;
if (Size mod Sizeof(Buffer))<> 0 then
begin
read:= Stream.Read(Buffer,Size mod Sizeof(Buffer));
Update(Buffer,read);
end;
end;
我还查看了其他一些库,例如 Delphi Encryption Compedium (http://home.netsurf.de/wolfgang.ehrhardt/crchash_en.html) 和 Wolfgang Ehrhardt 库 (http://www.torry.net /pages.php?id=519#939342),也是 DoubleCommander 中包含的一个,但出于各种原因(很简单),我正在尝试使用 DCPCrypt 来执行此操作。
【问题讨论】:
标签: freepascal lazarus buffer