DigestData: MD5/SHA-1 Hash Calculator Script

M. Gallant 10/08/2000

The ability to create objects from classes in the Java API can be used to extend the capability of Windows scripts. Since the MS Java API is resident on any PC with IE4+ installed, developers can leverage the capability contained therein.
The following script instantiates a Java object which contains a method DigestsMD5SHA1.getBothDigests(String filename) to return the digital hash digests for a specified file. The script reads arguments that can be both files, and directories; for directories, the files are enumerated (one level deep) and the hash values are calculated and displayed, along with the full file name, and its size in bytes. An easy way to use the vbs script is simply to drag & drop files and/or directories to calculate. To use the Java class, compile the Java source code, and place the resultant DigestsMD5SHA1.class class file in the classpath (for example: C:\Windows\Java\Classes)

DigestData.vbs

'**************************************************************** ' File: DigestData.vbs (WSH for VBscript) ' Author: (c) M. Gallant 10/08/2000 ' ' Calculates MD5 and SHA-1 hash values ' Uses Java class "DigestsMD5SHA1" which must be in classpath. ' Drag & drop files and/or folders; for folders, calculates ' hash values for files in folder (not subfolders). '**************************************************************** Option Explicit Dim WshShell, fso, oJDigests, oFiles DIM digestdata, digestfile, alldata, fileargs, i, j, fsize, again set WshShell = WScript.CreateObject("WScript.Shell") set fso = WScript.CreateObject("Scripting.FileSystemObject") set oJDigests = GetObject("java:DigestsMD5SHA1") 'Instantiate Java object via moniker. Set fileargs = WScript.Arguments If fileargs.Count<1 Then WScript.Echo "Drag some files and/or folders onto the icon" WScript.Quit End If For i = 0 to fileargs.Count -1 'Get all arguments passes (or drag/dropped). digestfile = fileargs(i) If fso.FileExists(digestfile) Then fsize = fso.getFile(digestfile).Size ' file size in bytes. digestdata = oJDigests.getBothDigests(digestfile) ' get MD5 and SHA1 digests. alldata = digestfile & " [" & fsize & " bytes]" & vbCrLf & digestdata ElseIF fso.FolderExists(digestfile) Then Set oFiles = fso.GetFolder(digestfile).Files alldata = "" For Each j In oFiles ' enumerate through all files one level deep in folder. fsize = j.Size digestdata = oJDigests.getBothDigests(j) ' get MD5 and SHA1 digests. alldata = alldata & j & " [" & fsize & " bytes]" & _ vbCrLf & digestdata & vbCrLf Next Else alldata = "Argument is neither file nor folder." End If again = WshShell.Popup(alldata & vbCrLf & vbCrLf & "Continue?",0, _ "Cryptographic MD5/SHA-1 Hash Calculator -- M. Gallant", vbInformation + vbYesNo) If again = vbNo Then Exit For Next '----------------- End Script -------------------------------

DigestsMD5SHA1.java (Java class)

/* DigestsMD5SHA1 provides digital hash values for MD5 and SHA-1 algorithms from one method, for file passed in. M. Gallant 10/08/2000 */ import java.io.*; import java.security.*; public final class DigestsMD5SHA1 { private String filename = null; private MessageDigest currentAlgorithm; public String getBothDigests(String filename) { StringBuffer digestvalues = new StringBuffer() ; if ((new File(filename)).exists()){ // ------------- SHA-1 ----------------- digestvalues.append("------- SHA-1 ------- \r\n") ; try { currentAlgorithm = MessageDigest.getInstance("SHA-1"); digestvalues.append(computeDigest(loadBytes(filename)) + "\r\n"); } catch(NoSuchAlgorithmException e){ digestvalues.append("SHA-1 algorithm not available."); } // ------------- MD5 ----------------- digestvalues.append("------- MD5 ------- \r\n") ; try { currentAlgorithm = MessageDigest.getInstance("MD5"); digestvalues.append(computeDigest(loadBytes(filename)) + "\r\n"); } catch(NoSuchAlgorithmException e){ digestvalues.append("MD5 algorithm not available."); } return digestvalues.toString() ; } else { digestvalues.append(filename + " not found.") ; return digestvalues.toString() ; } } private byte[] loadBytes(String name) { FileInputStream in = null; try { in = new FileInputStream(name); ByteArrayOutputStream buffer = new ByteArrayOutputStream(); int bytesread = 0; byte [] tbuff = new byte[512] ; while(true) { bytesread = in.read(tbuff); if (bytesread == -1) // if EOF break ; buffer.write(tbuff,0,bytesread) ; } return buffer.toByteArray(); } catch (IOException e){ if (in != null) { try { in.close(); } catch (IOException e2) {} } return null; } } private String computeDigest(byte[] b){ currentAlgorithm.reset(); currentAlgorithm.update(b); byte[] hash = currentAlgorithm.digest(); String d = " "; int usbyte = 0; // unsigned byte for (int i = 0; i < hash.length; i+=2){ // format with 2-byte words with spaces. usbyte = hash[i] & 0xFF ; // byte-wise AND converts signed byte to unsigned. if(usbyte<16) d += "0" + Integer.toHexString(usbyte); // pad on left if single hex digit. else d += Integer.toHexString(usbyte); usbyte = hash[i+1] & 0xFF ; // byte-wise AND converts signed byte to unsigned. if(usbyte<16) d += "0" + Integer.toHexString(usbyte) + " "; // pad on left if single hex digit. else d += Integer.toHexString(usbyte) + " "; } return d.toUpperCase(); } public static void main(String args[]) { DigestsMD5SHA1 digs = new DigestsMD5SHA1() ; String digsdata = digs.getBothDigests(args[0]) ; System.out.println(digsdata) ; } }