Skip to content

Instantly share code, notes, and snippets.

@HoShiMin
Created December 14, 2015 15:29
Show Gist options
  • Save HoShiMin/cca84618edac79be1d1f to your computer and use it in GitHub Desktop.
Save HoShiMin/cca84618edac79be1d1f to your computer and use it in GitHub Desktop.
Распараллеленная хэшировалка на основе cHash
unit HashMaster;
interface
uses
Windows, Classes, System.SysUtils, System.Threading, cHash, CodepageAPI;
type
THashTask = record
Calculate : Boolean;
Value : string;
end;
THashes = record
CRC32 : THashTask;
MD5 : THashTask;
SHA1 : THashTask;
SHA256 : THashTask;
SHA384 : THashTask;
SHA512 : THashTask;
end;
procedure CalculateHashes(Data: Pointer; Size: Integer; var Hashes: THashes);
implementation
var
ThreadPool: TThreadPool;
procedure CalculateHashes(Data: Pointer; Size: Integer; var Hashes: THashes);
var
Handles: packed record
CRC32 : THandle;
MD5 : THandle;
SHA1 : THandle;
SHA256 : THandle;
SHA384 : THandle;
SHA512 : THandle;
end;
LocalHashes: record
CRC32 : string;
MD5 : string;
SHA1 : string;
SHA256 : string;
SHA384 : string;
SHA512 : string;
end;
begin
Handles.CRC32 := CreateEvent(nil, True, not Hashes.CRC32.Calculate , nil);
Handles.MD5 := CreateEvent(nil, True, not Hashes.MD5.Calculate , nil);
Handles.SHA1 := CreateEvent(nil, True, not Hashes.SHA1.Calculate , nil);
Handles.SHA256 := CreateEvent(nil, True, not Hashes.SHA256.Calculate, nil);
Handles.SHA384 := CreateEvent(nil, True, not Hashes.SHA384.Calculate, nil);
Handles.SHA512 := CreateEvent(nil, True, not Hashes.SHA512.Calculate, nil);
if Hashes.CRC32.Calculate then ThreadPool.QueueWorkItem(procedure()
begin
LocalHashes.CRC32 := LowerCase(IntToHex(CalcCRC32(Data^, Size), 8));
SetEvent(Handles.CRC32);
end) else Hashes.CRC32.Value := '';
if Hashes.MD5.Calculate then ThreadPool.QueueWorkItem(procedure()
begin
LocalHashes.MD5 := AnsiToWide(MD5DigestToHex(CalcMD5(Data^, Size)));
SetEvent(Handles.MD5);
end) else Hashes.MD5.Value := '';
if Hashes.SHA1.Calculate then ThreadPool.QueueWorkItem(procedure()
begin
LocalHashes.SHA1 := AnsiToWide(SHA1DigestToHex(CalcSHA1(Data^, Size)));
SetEvent(Handles.SHA1);
end) else Hashes.SHA1.Value := '';
if Hashes.SHA256.Calculate then ThreadPool.QueueWorkItem(procedure()
begin
LocalHashes.SHA256 := AnsiToWide(SHA256DigestToHex(CalcSHA256(Data^, Size)));
SetEvent(Handles.SHA256);
end) else Hashes.SHA256.Value := '';
if Hashes.SHA384.Calculate then ThreadPool.QueueWorkItem(procedure()
begin
LocalHashes.SHA384 := AnsiToWide(SHA384DigestToHex(CalcSHA384(Data^, Size)));
SetEvent(Handles.SHA384);
end) else Hashes.SHA384.Value := '';
if Hashes.SHA512.Calculate then ThreadPool.QueueWorkItem(procedure()
begin
LocalHashes.SHA512 := AnsiToWide(SHA512DigestToHex(CalcSHA512(Data^, Size)));
SetEvent(Handles.SHA512);
end) else Hashes.SHA512.Value := '';
WaitForMultipleObjects(SizeOf(Handles) div SizeOf(THandle), @Handles, TRUE, INFINITE);
CloseHandle(Handles.CRC32);
CloseHandle(Handles.MD5);
CloseHandle(Handles.SHA1);
CloseHandle(Handles.SHA256);
CloseHandle(Handles.SHA384);
CloseHandle(Handles.SHA512);
Hashes.CRC32.Value := LocalHashes.CRC32;
Hashes.MD5.Value := LocalHashes.MD5;
Hashes.SHA1.Value := LocalHashes.SHA1;
Hashes.SHA384.Value := LocalHashes.SHA384;
Hashes.SHA256.Value := LocalHashes.SHA256;
Hashes.SHA512.Value := LocalHashes.SHA512;
end;
initialization
ThreadPool := TThreadPool.Create;
ThreadPool.SetMaxWorkerThreads(TThread.ProcessorCount);
ThreadPool.SetMinWorkerThreads(TThread.ProcessorCount);
finalization
FreeAndNil(ThreadPool);
end.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment