Как передать больший размер буфера в процедуру DCPcrypt ‘UpdateStream’

#freepascal #lazarus #buffer

#freepascal #лазарь #буфер

Вопрос:

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

С тех пор я добавил возможность использовать MD5, SHA256 и SHA512 с помощью библиотеки DCPcrypt (http://wiki.lazarus .freepascal.org/DCPcrypt или 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
 

Однако мои функции и процедуры хеширования теперь перенесены в единую функцию, управляемую переключателем status, чтобы сделать мой код более объектно-ориентированным. В основном в нем закодированы все 4 параметра хеширования, и какой раздел запускается, зависит от того, какая радиокнопка установлена.Проверенный статус, который находит программа. Код 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 МБ занимает 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:

Чтобы ответить на ваш вопрос: вы не можете передать другой размер, но вы можете изменить размер массива в 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%).

Комментарии:

1. Привет. Это вывод, к которому я начал приходить на самом деле, поэтому спасибо за разъяснение этого момента для меня. Я думаю, что я буду использовать функции MD5 и SHA1 FPC для этих двух переключателей, а затем использовать DCPcrypt для SHA256 и SHA512. Хотя я признаю, что эти два не будут вычисляться массово быстро, по крайней мере, это предоставляет пользователю возможность, которая является моей целью. Я просто хотел попробовать и сделать это как можно быстрее. Еще раз спасибо