"SHA-1 Hash" - http://discuss.visual-prolog.com/viewtopic.php?t=8225
"MDI Extension" - http://discuss.visual-prolog.com/viewtopic.php?t=7958
Here is yet another way to compute MD5 and SHA-1, using Microsoft's CtyptoAPI.
Code: Select all
constants
md5 = 32771. % CALG_MD5 = 32771.
sha = 32772. % CALG_SHA = 32772.
nullstr : string = uncheckedConvert(string,0).
class predicates % Externals
cryptAcquireContext: (unsigned HProvider, string Null, string Null, unsigned32 ProvType, unsigned Flags)
-> boolean procedure (o,i,i,i,i) language stdcall as "_CryptAcquireContextW@20".
cryptCreateHash : (unsigned HProvider, integer AlgID, integer Key, unsigned32 Flags, unsigned Hash)
-> boolean procedure (i,i,i,i,o) language apicall.
cryptHashData : (unsigned HashHandle, string8 Data, byteCount DataLen, unsigned32 Flags)
-> boolean procedure language stdcall as "_CryptHashData@16".
cryptGetHashParam: (unsigned HashHandle, unsigned32 Param, binary DataOut, ptrInteger LenIO, unsigned32 Flags)
-> boolean procedure language apicall.
cryptDestroyHash: (unsigned HashHandle) -> boolean procedure language apicall.
cryptReleaseContext: (unsigned HProvider, unsigned32 Flags) -> boolean procedure language apicall.
class predicates
cryptHash : (string ToHash, integer AlgorithmID) -> string Hash.
clauses
cryptHash(InputStr, AlgorID) = Hash :-
if AlgorID=md5 then HashLen = 16 else HashLen = 20 end if,
_ = cryptAcquireContext(HProvider, nullstr, nullstr, 1, 0xF0000000),
_ = cryptCreateHash(HProvider, AlgorID, 0, 0, HHash),
InputStr8 = string8::mapFromString(InputStr),
InputLen = string8::length(InputStr8),
_ = cryptHashData(HHash, InputStr8 , InputLen, 0),
HashBuff = binary::createAtomic(HashLen),
HashBuffLen = mkPtr(HashLen),
_ = cryptGetHashParam(HHash, 2, HashBuff, HashBuffLen, 0), % HP_HASHVAL = 2.
BinStr = toString(HashBuff), % e.g. BinStr = $[90,01,50,...,72]
BinStrInner = string::subString(BinStr, 2, HashLen*3-1),
BinStrUp = text::textReplaceAll(BinStrInner, ",", ""),
Hash = string::toLowerCase(BinStrUp),
_ = cryptDestroyHash(HHash),
_ = cryptReleaseContext(HProvider, 0).
class predicates
mkPtr : (integer V) -> ptrInteger PV.
clauses
mkPtr(V) = ptr(V).
% Test Results:
% MD5 "a" = 0cc175b9c0f1b6a831c399e269772661
% MD5 "abc" = 900150983cd24fb0d6963f7d28e17f72
% SHA "apple" = d0be2dc421be4fcd0172e5afceea3970e2f3d940