Как передать больший размер буфера в DCPCrypt UpdateStream - PullRequest
2 голосов
/ 01 ноября 2011

У меня есть программа, которая в настоящее время хэширует файлы, используя только SHA1.Других вариантов нет.Он хэширует их, используя хеш-функцию SHA1, которая является частью компилятора Lazarus и Free Pascal.

С тех пор я добавил возможность использовать MD5, SHA256 и SHA512 с помощью библиотеки DCPCrypt (http://wiki.lazarus.freepascal.org/DCPcrypt или * 1004).*http://www.cityinthesky.co.uk/opensource). Все работает нормально, однако моя более ранняя версия хэшировала файл в буферах 2 МБ, если файл был больше 1 МБ. Если он был меньше 1 МБ, он использовал буфер по умолчанию в 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  

Мой вопрос заключается в том, как добавить размер буфера в varSHA1Hash.UpdateStream, еслинайден файл «большой» (скажем, больше 1 МБ)? Это важно, потому что файл размером 300 МБ, например, таkes 4 секунды с моей более ранней версией, и теперь это занимает 9 секунд с моей «улучшенной» версией, которая использует библиотеку DCPCrypt!Таким образом, это удвоило время, необходимое для больших файлов, хотя мой код читается намного лучше.Если я смогу заставить varSHA1Hash.UpdateStream считывать данные по несколько Мб за раз вместо 8-килобайтных буферов (что делает процедура 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) и библиотека Вольфганга Эрхардта (http://www.torry.net/pages.php?id=519#939342)), а также библиотека, включенная в DoubleCommander, но по разным причинам (простота - единица) Я пытаюсь сделать это с помощью DCPCrypt.

1 Ответ

3 голосов
/ 01 ноября 2011

Чтобы ответить на ваш вопрос: вы не можете передать другой размер, но вы можете изменить размер массива в dcpcrypt2.pas в методе, который вы упомянули, и перекомпилировать DCPCrypt, в конце концов, это OSS.

Но это не сильно поможет, потому что модуль sha1 в fpc не быстрее из-за большего размера буфера, но из-за более быстрой реализации алгоритма sha1, он использует встроенные функции компилятора для поворота значений, которые интенсивно используются работа алгоритма sha1.

Просто следующая программа с различными числовыми параметрами командной строки (например, 8192 и 8388608):

uses
  sysutils,sha1;

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

По крайней мере, на моем ПК не имеет значения, если буфер 8 КБ или 8 МБ. Если вы используете более низкие значения, такие как 1024, вы увидите небольшое замедление (10-20%).

...