Generate checksums for files
cpr
This simple (Windows) function uses the certutil function built into Windows for computing the hash of a file from a choice of algorithms.
A file containing the computed hash is generated, the hash is returned, and printed to history - whichever you like.
Function can be called from inside another function, command line, or executed interactively.
In line e.g. String hash = getHash("C:\path\some.file","MD5",quiet=1)
From the command line e.g.: getHash("C:\path\some.file","MD5")
// menu
Menu "Tools"
"Generate checksum",/Q, getHashManually()
end
// List of built-in Windows hash functions provided by CertUtil
Static StrConstant hashFuncLst="MD2;MD4;MD5;SHA1;SHA256;SHA384;SHA512;"
//___________________________________________________________________________________________________
// Function to get the hash of an input file (objectStr) output as a text file (eg .md5), a string variable, and printed to history
// Valid values for hashFunc: MD2 MD4 MD5 SHA1 SHA256 SHA384 SHA512
// Synax - cmd.exe /C certutil -hashfile C:\\file.txt MD5
Function/S getHash(String ObjectStr,String hashFunc[,Variable quiet])
String fileHash="", LineStr="", PathStr, fexts
Variable fileID,i
// make the file extension (lowercase)
fexts=LowerStr(hashFunc)[0,2]
// make sure the path is in windows form
ObjectStr=ParseFilePath(5, ObjectStr, "\\", 0, 0)
// make a new path in the location of the file to be hashed
PathStr = ParseFilePath(1, ObjectStr, "\\", 1, 0)
NewPath /O/Q/Z ObjectPath, PathStr
// execut cmd script
ExecuteScriptText/B/Z "cmd.exe /C certutil -hashfile \""+ObjectStr+"\" "+hashFunc
// read the output from the getHash command
do
LineStr = StringFromList(i,S_value, "\n")
// Success
if (Stringmatch(lineStr, hashFunc+" hash of "+ ObjectStr +":\r"))
fileHash = StringFromList(i+1,S_value, "\n")
// make a new hash file without the other CMD lines in it
open /P=ObjectPath fileID as ParseFilePath(3, ObjectStr, "\\", 0, 0)+"."+fexts
fprintf fileID, replaceString("\r",StringFromList(i+1,S_value, "\n"),"")
close fileID
// print output
if (paramisDefault(quiet))
Print hashFunc+" hash of "+ParseFilePath(0, ObjectStr, "\\", 1, 0)+": "+fileHash
endif
Break
// Handle other errors
else
if (paramisDefault(quiet))
Print "There was a problem generating a "+hashFunc+" hash for "+ParseFilePath(0, ObjectStr, "\\", 1, 0)
endif
break
endif
i+=1
while (i < ItemsInList(S_value, "\n"))
return fileHash
end
//___________________________________________________________________________________________________
// Function to allow manual generation of checksum
Function getHashManually()
Open/D/R/MULT=1/F="*"/M="Select files for generating a checksum" fileID
if(strlen(S_fileName)==0)
return 0 // user didn't choose a file
else
S_filename=replacestring("\r",S_filename,";")
endif
String hashFunc
Prompt hashFunc "Choose a checksum method", popup hashFuncLst
DoPrompt/HELP="" "Checksum generator" hashFunc
If (V_flag!=0)
return 0 // user hit cancel
endif
Variable i
for (i=0;i<itemsinlist(S_filename);i+=1)
gethash(stringfromlist(i,S_filename),hashFunc)
endfor
end
//___________________________________________________________________________________________________
Menu "Tools"
"Generate checksum",/Q, getHashManually()
end
// List of built-in Windows hash functions provided by CertUtil
Static StrConstant hashFuncLst="MD2;MD4;MD5;SHA1;SHA256;SHA384;SHA512;"
//___________________________________________________________________________________________________
// Function to get the hash of an input file (objectStr) output as a text file (eg .md5), a string variable, and printed to history
// Valid values for hashFunc: MD2 MD4 MD5 SHA1 SHA256 SHA384 SHA512
// Synax - cmd.exe /C certutil -hashfile C:\\file.txt MD5
Function/S getHash(String ObjectStr,String hashFunc[,Variable quiet])
String fileHash="", LineStr="", PathStr, fexts
Variable fileID,i
// make the file extension (lowercase)
fexts=LowerStr(hashFunc)[0,2]
// make sure the path is in windows form
ObjectStr=ParseFilePath(5, ObjectStr, "\\", 0, 0)
// make a new path in the location of the file to be hashed
PathStr = ParseFilePath(1, ObjectStr, "\\", 1, 0)
NewPath /O/Q/Z ObjectPath, PathStr
// execut cmd script
ExecuteScriptText/B/Z "cmd.exe /C certutil -hashfile \""+ObjectStr+"\" "+hashFunc
// read the output from the getHash command
do
LineStr = StringFromList(i,S_value, "\n")
// Success
if (Stringmatch(lineStr, hashFunc+" hash of "+ ObjectStr +":\r"))
fileHash = StringFromList(i+1,S_value, "\n")
// make a new hash file without the other CMD lines in it
open /P=ObjectPath fileID as ParseFilePath(3, ObjectStr, "\\", 0, 0)+"."+fexts
fprintf fileID, replaceString("\r",StringFromList(i+1,S_value, "\n"),"")
close fileID
// print output
if (paramisDefault(quiet))
Print hashFunc+" hash of "+ParseFilePath(0, ObjectStr, "\\", 1, 0)+": "+fileHash
endif
Break
// Handle other errors
else
if (paramisDefault(quiet))
Print "There was a problem generating a "+hashFunc+" hash for "+ParseFilePath(0, ObjectStr, "\\", 1, 0)
endif
break
endif
i+=1
while (i < ItemsInList(S_value, "\n"))
return fileHash
end
//___________________________________________________________________________________________________
// Function to allow manual generation of checksum
Function getHashManually()
Open/D/R/MULT=1/F="*"/M="Select files for generating a checksum" fileID
if(strlen(S_fileName)==0)
return 0 // user didn't choose a file
else
S_filename=replacestring("\r",S_filename,";")
endif
String hashFunc
Prompt hashFunc "Choose a checksum method", popup hashFuncLst
DoPrompt/HELP="" "Checksum generator" hashFunc
If (V_flag!=0)
return 0 // user hit cancel
endif
Variable i
for (i=0;i<itemsinlist(S_filename);i+=1)
gethash(stringfromlist(i,S_filename),hashFunc)
endfor
end
//___________________________________________________________________________________________________
Forum
Support
Gallery
Igor Pro 9
Learn More
Igor XOP Toolkit
Learn More
Igor NIDAQ Tools MX
Learn More
For what it's worth, Igor has functions that can be used to calculate many of these hashes. The hash() function is for strings, and the WaveHash() function for waves. These have the disadvantage that you'd need to read the file's data into Igor (probably as a string using FBinRead) but the advantage of being cross platform and not needing to rely on ExecuteScriptText.
November 9, 2020 at 07:42 am - Permalink
Here is a platform independent version :
Menu "Tools"
"Generate checksum",/Q, getHashManually()
End
// List of built-in Igor hash functions
Static StrConstant hashFuncLst="MD4;MD5;SHA1;SHA224;SHA256;SHA384;SHA512;"
//___________________________________________________________________________________________________
// Function to get the hash of an input file (objectStr) output as a text file (eg .md5), a string variable, and printed to history
// Valid values for hashFunc: MD4 MD5 SHA1 SHA256 SHA384 SHA512
// uses igor built in hash functions replaces using certutils
Function/S getHash(String ObjectStr,String hashFunc[,Variable quiet])
DFREF dfrSave = GetDataFolderDFR()
String fileHash="unavailable",fexts=LowerStr(hashFunc)[0,2]
int refNum,method = getHashMethod(hashFunc)
SetDataFolder NewFreeDataFolder() // Create new free data folder
// load the entire file/archive as a binary wave
GBLoadWave/T={72,72}/W=1/Q/A=hashWv ObjectStr
if (V_flag) // V_flag == 1 if successful
Wave hashWv0
// generate a hash on the entire wave
fileHash = WaveHash(hashWv0,method)
// write hash key to a notebook and save
Open refNum as S_path + ParseFilePath(3, ObjectStr, ":", 0, 0)+"."+fexts
FBinWrite refNum, fileHash
Close refNum
// print output
if (!quiet)
Print hashFunc+" hash of "+ParseFilePath(0, ObjectStr, ":", 1, 0)+": "+fileHash
endif
else
if (!quiet)
Print "There was a problem generating a "+hashFunc+" hash for "+ParseFilePath(0, ObjectStr, ":", 1, 0)
endif
endif
SetDataFolder dfrSave
return fileHash
End
//___________________________________________________________________________________________________
// return the hash method argument for Hash() and WaveHash()functions
Static Function getHashMethod(String hashFuncStr)
int method
strswitch (hashFuncStr)
case "SHA256":
method=1
break
case "MD4":
method=2
break
case "MD5":
method=3
break
case "SHA1":
method=4
break
case "SHA224":
method=5
break
case "SHA384":
method=6
break
case "SHA512":
method=7
break
endswitch
return method
End
//___________________________________________________________________________________________________
// Function to allow manual generation of checksum
Function getHashManually()
Open/D/R/MULT=1/F="*"/M="Select files for generating a checksum" fileID
if(strlen(S_fileName)==0)
return 0 // user didn't choose a file
endif
String hashFunc,fName
Prompt hashFunc "Choose a checksum method", popup hashFuncLst
DoPrompt/HELP="" "Checksum generator" hashFunc
if (V_flag!=0)
return 0 // user hit cancel
endif
// loop through the list of files
for (fName : ListToTextWave(S_filename,"\r"))
gethash(fName,hashFunc)
endfor
End
//___________________________________________________________________________________________________
May 28, 2021 at 08:21 am - Permalink