/** * Copyright (c) 2008, Aberystwyth University * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * - Neither the name of the Centre for Advanced Software and * Intelligent Systems (CASIS) nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ 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])); } }