【问题标题】:How to pass a larger buffer size to DCPCrypt 'UpdateStream' Procedure如何将更大的缓冲区大小传递给 DCPCrypt 'UpdateStream' 过程
【发布时间】: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


    【解决方案1】:

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

    但这无济于事,因为 fpc 的 sha1 单元不是因为缓冲区大小更快,而是因为 sha1 算法的实现更快,它利用编译器内在函数来旋转值,这是一个经常使用的值sha1算法的操作。

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

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

    至少在我的 PC 上,缓冲区是 8k 还是 8M 没有区别。如果您使用较低的值(例如 1024),您会看到速度略有下降 (10-20%)。

    【讨论】:

    • 嗨。这实际上是我开始得出的结论,所以感谢您为我澄清这一点。我想我要做的是对这两个单选按钮使用 MD5 和 SHA1 FPC 功能,然后对 SHA256 和 SHA512 使用 DCPCrypt。虽然我承认这两个计算不会很快,但至少它为用户提供了选择,这是我的目标。我只是想尝试让它尽可能快。再次感谢
    猜你喜欢
    • 2010-10-11
    • 2015-08-13
    • 2021-08-07
    • 1970-01-01
    • 2013-06-14
    • 2015-10-26
    • 1970-01-01
    • 2015-06-28
    • 1970-01-01
    相关资源
    最近更新 更多