
Delphi 默认没有WinCrypt相关函数的定义所以引用JwaWinCrypt{jedi-apilib}单元
将 CryptCreateHash(hProv, CALG_MD5,0, 0, hHash)中的参数CALG_MD5
修改为CALG_SHA1即为计算SHA1哈希 值得注意的时CALG_SHA_256,CALG_SHA_384,CALG_SHA_512
着三个算法是在Windows XP SP3才开始支持的 XP SP2~ Win2000是不支持的!!
program Project2;
{$APPTYPE CONSOLE}
uses
Winapi.Windows,
System.SysUtils,
System.Classes,
System.Math,
JwaWinCrypt;
Function GetFileSizeEx(hFile: THandle; Var lpFileSizeHigh :UInt64):Boolean; stdcall; external kernel32 name 'GetFileSizeEx';
Function GetFileHash4Md5(FileDirectory :PChar):String;
Const
Buffer_Threshold = 1024 * 1024;
Label OnFail;
Var
hFile :THandle;
hMapFile :THandle;
dwFileSize :UInt64;
dwFileSizeH:DWORD;
hProv :HCRYPTPROV;
hHash :HCRYPTHASH;
iIndex :UInt64;
dwBufSize :DWORD;
lpBuffer :PByte;
lpHash :Array [0..MAXCHAR] Of Byte;
dwHashLen :DWORD;
szHash :Array [0..MAXCHAR] Of Char;
begin
Writeln('文件:', FileDirectory);
Result := '';
lpBuffer := Nil;
hMapFile := INVALID_HANDLE_VALUE;
hFile := CreateFile(FileDirectory, GENERIC_READ, FILE_SHARE_READ, Nil,OPEN_EXISTING, 0, 0);
if hFile = INVALID_HANDLE_VALUE then
begin
Writeln('CreateFile Error, ErrorCode:', GetLastError);
Goto OnFail;
end;
if Not GetFileSizeEx(hFile, dwFileSize) then
begin
Writeln('GetFileSizeEx Error, ErrorCode:', GetLastError);
Goto OnFail;
end;
Writeln('大小:', dwFileSize, ' 字节');
hMapFile := CreateFileMapping(hFile, Nil, PAGE_READONLY, 0, 0, Nil);
if hMapFile = INVALID_HANDLE_VALUE then
begin
Writeln('CreateFileMapping Error, ErrorCode:', GetLastError);
Goto OnFail;
end;
if Not CryptAcquireContext(hProv, Nil, Nil, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT Or CRYPT_MACHINE_KEYSET) Then
begin
Writeln('CryptAcquireContext Error, ErrorCode:', GetLastError);
Goto OnFail;
end;
if Not CryptCreateHash(hProv, CALG_MD5,0, 0, hHash) Then
begin
Writeln('CryptCreateHash Error, ErrorCode:', GetLastError);
Goto OnFail;
end;
iIndex := 0;
while iIndex < dwFileSize do
begin
dwBufSize := Min(dwFileSize - iIndex, Buffer_Threshold);
lpBuffer := MapViewOfFile(hMapFile, FILE_MAP_READ, Int64Rec(iIndex).Hi, Int64Rec(iIndex).Lo, dwBufSize);
if lpBuffer = Nil then
begin
Writeln('MapViewOfFile Error, ErrorCode:', GetLastError);
Goto OnFail;
end;
if Not CryptHashData(hHash, lpBuffer, dwBufSize, 0) then
begin
Writeln('CryptHashData Error, ErrorCode:', GetLastError);
Goto OnFail;
end;
UnmapViewOfFile(lpBuffer);
Inc(iIndex, Buffer_Threshold);
end;
dwBufSize := SizeOf(DWORD);
dwHashLen := 0;
if CryptGetHashParam(hHash, HP_HASHSIZE, @dwHashLen, dwBufSize, 0) then
begin
ZeroMemory(@lpHash, SizeOf(lpHash));
if CryptGetHashParam(hHash, HP_HASHVAL, @lpHash, dwHashLen, 0) Then
begin
for dwFileSizeH := 0 to dwHashLen-1 do
begin
wsprintf(@szHash, '%s%02x', szHash, lpHash[dwFileSizeH]);
end;
Writeln('MD5:', String(szHash));
end Else
begin
Writeln('Error getting hash value, ErrorCode:', GetLastError);
Goto OnFail;
end;
end Else
begin
Writeln('Error getting hash length value, ErrorCode:', GetLastError);
Goto OnFail;
end;
OnFail:
CryptDestroyHash(hHash);
CryptReleaseContext(hProv, 0);
UnmapViewOfFile(lpBuffer);
CloseHandle(hFile);
CloseHandle(hMapFile);
end;
begin
GetFileHash4Md5('E:\ISO\cn_windows_server_2016_updated_feb_2018_x64_dvd_11636703.iso');
Readln;
end.