Generate checksums for files

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
//___________________________________________________________________________________________________	

 

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.

Here is a platform independent version :

// menu
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
//___________________________________________________________________________________________________	

 

Forum

Support

Gallery

Igor Pro 10

Learn More

Igor XOP Toolkit

Learn More

Igor NIDAQ Tools MX

Learn More