All Downloads are FREE. Search and download functionalities are using the official Maven repository.

at.spardat.xma.boot.transform.HashChecksum Maven / Gradle / Ivy

There is a newer version: 1.16.0
Show newest version
/*******************************************************************************
 * Copyright (c) 2003, 2007 s IT Solutions AT Spardat GmbH .
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     s IT Solutions AT Spardat GmbH - initial API and implementation
 *******************************************************************************/

/*
 * @(#) $Id: HashChecksum.java 2084 2007-11-27 14:53:31Z s3460 $
 */
package at.spardat.xma.boot.transform;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.DigestInputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

import at.spardat.xma.boot.logger.LogLevel;
import at.spardat.xma.boot.logger.Logger;
import at.spardat.xma.boot.util.Util;


/**
 * Class for calculation checksum values for jar-files and plain files.
 * For jar-files a MD5-hash is calculated over the contents of all files contained in
 * the jar-file. Only the contents of the files determine the hash value, their names,
 * timestamps etc. do not influence the hash value.
 * For plain files (text files, native libs, etc.) a MD5-hash is clalculated over the content
 * of the file.
 * @author s2877
 * @since 1.3.0
 */
public class HashChecksum {

    /**
     * Size of the read buffer to use.
     */
    private static int readBufferSize = 8 * 1024;

    /**
     * Calculates the hasvalue for jar-files. It is calculated over all contained
     * files. The order of the files in the jar-file is significant. The timestamps of the files
     * do not influence the hash value.
     * @param file the jar-file to calculate the hash value for.
     * @return the calculated checksum
     * @throws IOException on errors reading the file
     */
    public static String calcJarCheckSum(File file) throws IOException {
        MessageDigest messageDigest;
        byte[] buf = new byte[readBufferSize];
        JarFile jarfile = null;
        try {
            jarfile = new JarFile(file);

            try {
                messageDigest = MessageDigest.getInstance("MD5");
            } catch (NoSuchAlgorithmException noalgo) {
                throw new RuntimeException(noalgo);
            }

            for (Enumeration e = jarfile.entries() ; e.hasMoreElements() ;) {
                JarEntry entry =  (JarEntry)e.nextElement();
                if(!entry.isDirectory() && !"META-INF/MANIFEST.MF".equalsIgnoreCase(entry.getName()) ) {
    //              if(verbose) System.out.println( "element: " + entry.getName() );
                  InputStream is = jarfile.getInputStream( entry );
                  DigestInputStream dis = new DigestInputStream(is, messageDigest);

                  while (dis.read(buf, 0, readBufferSize) != -1) {
                      ;
                  }
                  dis.close();
                  is.close();
                } // end if not directory

            }
        } finally {
            try {
                if(jarfile!=null) jarfile.close();
            } catch (Exception ex) {
                Logger.getLogger("bootrt.bootRuntime").log(LogLevel.WARNING,"error closing "+file.getAbsolutePath(),ex);
            }
        }

        byte[] fileDigest = messageDigest.digest ();
        return toHexString(fileDigest);
    }

    /**
     * Calculates the hashvalue for a plain file or a native lib. The binary content of the
     * file is hashed. Every change to the file content leads to a change in the resulting hash value.
     * @param file the jar-file to calculate the hash value for.
     * @return the calculated checksum
     * @throws IOException on errors reading the file
     * @since 1.3.0
     * @author s2877
     */
    public static String calcFileCheckSum(File file) throws IOException {
        MessageDigest messageDigest;
        InputStream is = null;
        DigestInputStream dis = null;
        try {
            messageDigest = MessageDigest.getInstance("MD5");
            is = new FileInputStream(file);
            dis = new DigestInputStream(is, messageDigest);
            byte[] buf = new byte[readBufferSize];
            while(dis.read(buf, 0, readBufferSize)>0);
            return toHexString(messageDigest.digest());
        } catch (NoSuchAlgorithmException noalgo) {
            throw new RuntimeException(noalgo);
        } finally {
            Util.close(dis,"digest input stream on "+file.getAbsolutePath());
            Util.close(is,file.getAbsolutePath());
        }
    }

    /**
     * Calculates the hashvalue over the content of a plain file or a native lib.
     * Every change to the given data leads to a change in the resulting hash value.
     * @param data the bytes over which to caluclate the checksum
     * @return the calculated checksum
     * @since 1.3.0
     * @author s2877
     */
    public static String calcCheckSum(byte[] data) {
        MessageDigest messageDigest;
        try {
            messageDigest = MessageDigest.getInstance("MD5");
            messageDigest.update(data);
            return toHexString(messageDigest.digest());
        } catch (NoSuchAlgorithmException noalgo) {
           throw new RuntimeException(noalgo);
        }
    }

    /**
     * Converts the given binary data int a hexadezimal string representation.
     * @param data to convert
     * @return the converted data
     * @since 1.3.0
     * @author s2877
     */
    public static String toHexString(byte[] data) {
        StringBuffer checksumSb = new StringBuffer();
        for (int i = 0; i < data.length; i++) {
            String hexStr = Integer.toHexString(0x00ff & data[i]);
            if (hexStr.length() < 2) {
                checksumSb.append("0");
            }
            checksumSb.append(hexStr);
        }
        return checksumSb.toString();
    }

    /**
     * Compare two application descriptor hash codes
     * @return true if both byte arrays contain the same sequence of bytes
     *         false otherwise
     */
    public static boolean areEqual( byte[] a, byte[] b ) {

        if( a==null || b==null || a.length != b.length) {
            return false;
        }
        for( int i=0; i




© 2015 - 2024 Weber Informatics LLC | Privacy Policy