如何将更大的缓冲区大小传递给DCPCrypt'UpdateStream'过程

时间:2011-10-31 21:35:50

标签: freepascal lazarus buffer

我有一个程序,目前只使用SHA1哈希文件。没有其他选择。它使用SHA1哈希函数对它们进行哈希处理,该函数是Lazarus和Free Pascal编译器的一部分。

我已经添加了使用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附带的那个,但出于varios的原因(简单是一个)我试图使用DCPCrypt来做这个。

1 个答案:

答案 0 :(得分:3)

回答你的问题:你不能传递不同的大小但你可以在你提到的方法中更改dcpcrypt2.pas中的数组大小并重新编译DCPCrypt,毕竟它是OSS。

但是这没有多大帮助,因为fpc的sha1单位由于缓冲区大小较大而不快,但由于sha1算法的实现速度更快,它利用编译器内在函数来旋转值大量使用的值sha1算法的操作。

以下程序只有不同的数字命令行参数(例如8192和8388608):

uses
  sysutils,sha1;

begin
  writeln(SHA1Print(SHA1File('bigfile',StrToInt(paramstr(1)))));
end.

至少在我的电脑上,如果缓冲区是8k或8M则没有区别。如果使用较低的值(如1024),您会看到轻微的减速(10-20%)。