Quick way to compute and compare hash on a file

I was searching an hour ago for an application to compute a hash string (outside Terminal) and let me easily compare what I think the hash value should be. I couldn’t find anything but mentions to the Terminal method, so I wrote a quick script for it. Use it as you wish (I’m just going to keep mine around for the occasional check).

The script prompts you to select a file to compute a hash on (using the Downloads folder as default), then asks for the hash type, then the hash value you think it should be. The rest is intuitive (and shown below).

It supports sha, sha1, md2, md5, mdc2, and rmd160.


global hashes

set hashes to {"sha", "sha1", "md2", "md5", "mdc2", "rmd160"}

dis("Ready to check a hash value?")

tell application "SystemUIServer"
	activate
	choose file with prompt "Pick a file to compute the hash of:" default location (path to downloads folder) without multiple selections allowed
end tell
set filepicked to the result
set fileposix to POSIX path of filepicked

set hashtype to "false"
repeat while hashtype is "false"
	tell application "SystemUIServer"
		activate
		choose from list hashes with prompt "Pick a hash type" without multiple selections allowed
	end tell
	set hashtype to the result as string
end repeat


inptxt("Please enter the " & hashtype & " hash string you think the file should have.")
set hash to the result as text

set thecmd to ("openssl " & hashtype & " " & fileposix) as text

set shelloutput to do shell script thecmd as text



set es to (offset of "=" in shelloutput)
set es to es + 2
set hend to (count of shelloutput)

set hashcalc to (text es thru hend of shelloutput)


if hashcalc = hash then
	dis("Looks like it's a match!" & return & return & "The hash input by the user was" & return & hash & return & return & "The hash calculated on the file was" & return & hashcalc)
else
	dis("Looks like they DO NOT MATCH. Check hash type?" & return & return & "The hash input by the user was" & return & hash & return & return & "The hash calculated on the file was" & return & hashcalc)
	
end if


on dis(disp)
	tell application "SystemUIServer"
		activate
		display dialog disp
	end tell
end dis

on inptxt(txt)
	set goodinp to false
	repeat while goodinp is false
		inp(txt)
		try
			set inpres to the text returned of the result
			if (count (inpres)) > 0 then
				set goodinp to true
			else
				dis("Please input something!")
			end if
		on error
			dis("Woops, something weird was entered...try again")
		end try
	end repeat
	return inpres
end inptxt

on inp(txt)
	tell application "SystemUIServer"
		activate
		display dialog txt default answer ""
	end tell
end inp

Thanks for posting. Why do you tell an invisible, unscriptable application to display the dialogs?

Telling SystemUIServer to do the displaying pushes display or input boxes to the front window. If it’s not used, prompts and displays sometimes get lost in the background, forcing th user to click a dock icon to show the window. It doesn’t happen often, but it’s easier to just use a subroutine to display text or prompts using this method.

Hmm. I’ve not seen that before. The usual ways are either to use ‘activate’ to bring the script itself to the front ” and not to put the dialog commands in ‘tell’ statements ” or, better still, to tell whatever application happens to be frontmost at the time to display them, which doesn’t interfere with the focus:

tell application (path to frontmost application as text)
	display dialog "Hello"
end tell

Of course, if you use the ‘note’ icon in a dialog, the icon will reflect the application displaying it, so you may want to take non-generic measures in that case.