/** * The contents of this file are subject to the license and copyright * detailed in the LICENSE and NOTICE files at the root of the source * tree and available online at * * http://www.dspace.org/license/ */ package org.purl.sword.base; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import org.apache.log4j.Logger; /** * Utility class that holds Checksum related methods. * * @author Neil Taylor, Stuart Lewis */ public class ChecksumUtils { /** Logger */ private static Logger log = Logger.getLogger(ChecksumUtils.class); /** * Generate an MD5 hash for the file that is specified in the * filepath. The hash is returned as a String representation. * * @param filepath The path to the file to load. * @return A string hash of the file. * @throws NoSuchAlgorithmException If the MD5 algorithm is * not supported by the installed virtual machine. * * @throws IOException If there is an error accessing the file. */ public static String generateMD5(String filepath) throws NoSuchAlgorithmException, IOException { return generateMD5(new FileInputStream(filepath)); } /** * Generate an MD5 hash for the file that is specified in the * filepath. The hash is returned as a String representation. * * @param md5Stream The InputStream to checksum. * @return A string hash of the file. * @throws NoSuchAlgorithmException If the MD5 algorithm is * not supported by the installed virtual machine. * * @throws IOException If there is an error accessing the file. */ public static String generateMD5(InputStream md5Stream) throws NoSuchAlgorithmException, IOException { String md5 = null; try { MessageDigest md = MessageDigest.getInstance("MD5"); md.reset(); byte[] bytes = new byte[1024]; int count = 0; while( (count = md5Stream.read(bytes)) != -1 ) { md.update(bytes, 0, count); } byte[] md5Digest = md.digest(); StringBuffer buffer = new StringBuffer(); for( byte b : md5Digest ) { // 0xFF is used to handle the issue of negative numbers in the bytes String hex = Integer.toHexString(b & 0xFF); if( hex.length() == 1 ) { buffer.append("0"); } buffer.append(hex); } md5 = buffer.toString(); } catch(NoSuchAlgorithmException ex ) { log.error("MD5 Algorithm Not found"); throw ex; } finally { if( md5Stream != null ) { md5Stream.close(); } } return md5; } /** * Generate an MD5 hash for the file that is specified in the * filepath. The hash is returned as a String representation. * * @param bytes The byte array to checksum. * @return A string hash of the file. * @throws NoSuchAlgorithmException If the MD5 algorithm is * not supported by the installed virtual machine. * * @throws IOException If there is an error accessing the file. */ public static String generateMD5(byte[] bytes) throws NoSuchAlgorithmException, IOException { String md5 = null; try { MessageDigest md = MessageDigest.getInstance("MD5"); md.reset(); md.update(bytes); byte[] md5Digest = md.digest(); StringBuffer buffer = new StringBuffer(); for( byte b : md5Digest ) { // 0xFF is used to handle the issue of negative numbers in the bytes String hex = Integer.toHexString(b & 0xFF); if( hex.length() == 1 ) { buffer.append("0"); } buffer.append(hex); } md5 = buffer.toString(); } catch(NoSuchAlgorithmException ex ) { log.error("MD5 Algorithm Not found"); throw ex; // rethrow } return md5; } /** * Run a simple test to process the file. * * @param args The command line arguments. * @throws NoSuchAlgorithmException If there was an error generating the MD5. * @throws IOException If there is an error accessing the file. */ public static void main(String[] args) throws NoSuchAlgorithmException, IOException { System.out.println(ChecksumUtils.generateMD5(args[0])); } }