performance improvements for large files

Former-commit-id: 6a49a7066cb01c613b5c6f07c8497601a88e7f8d
This commit is contained in:
Jeremy Long
2014-07-19 07:34:50 -04:00
parent 46702bbb5c
commit 2dcef25175

View File

@@ -1,9 +1,28 @@
/*
* This file is part of dependency-check-core.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Copyright (c) 2014 Jeremy Long. All Rights Reserved.
*/
package org.owasp.dependencycheck.utils; package org.owasp.dependencycheck.utils;
import java.io.BufferedInputStream;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.security.DigestInputStream;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.util.logging.Level; import java.util.logging.Level;
@@ -12,11 +31,7 @@ import java.util.logging.Logger;
/** /**
* Includes methods to generate the MD5 and SHA1 checksum. * Includes methods to generate the MD5 and SHA1 checksum.
* *
* This code was copied from Real's How To. It has been slightly modified. * @author Jeremy Long <jeremy.long@owasp.org>
*
* Written and compiled by Réal Gagnon ©1998-2012
*
* @author Real's How To: http://www.rgagnon.com/javadetails/java-0416.html
* *
*/ */
public final class Checksum { public final class Checksum {
@@ -25,6 +40,7 @@ public final class Checksum {
* The logger. * The logger.
*/ */
private static final Logger LOGGER = Logger.getLogger(Checksum.class.getName()); private static final Logger LOGGER = Logger.getLogger(Checksum.class.getName());
/** /**
* Private constructor for a utility class. * Private constructor for a utility class.
*/ */
@@ -32,30 +48,25 @@ public final class Checksum {
} }
/** /**
* <p>Creates the cryptographic checksum of a given file using the specified * <p>
* algorithm.</p> <p>This algorithm was copied and heavily modified from * Creates the cryptographic checksum of a given file using the specified algorithm.</p>
* Real's How To: http://www.rgagnon.com/javadetails/java-0416.html</p>
* *
* @param algorithm the algorithm to use to calculate the checksum * @param algorithm the algorithm to use to calculate the checksum
* @param file the file to calculate the checksum for * @param file the file to calculate the checksum for
* @return the checksum * @return the checksum
* @throws IOException when the file does not exist * @throws IOException when the file does not exist
* @throws NoSuchAlgorithmException when an algorithm is specified that does * @throws NoSuchAlgorithmException when an algorithm is specified that does not exist
* not exist
*/ */
public static byte[] getChecksum(String algorithm, File file) throws NoSuchAlgorithmException, IOException { public static byte[] getChecksum(String algorithm, File file) throws NoSuchAlgorithmException, IOException {
MessageDigest digest = MessageDigest.getInstance(algorithm);
InputStream fis = null; InputStream fis = null;
byte[] buffer = new byte[1024];
MessageDigest complete = MessageDigest.getInstance(algorithm);
int numRead;
try { try {
fis = new FileInputStream(file); fis = new FileInputStream(file);
do { BufferedInputStream bis = new BufferedInputStream(fis);
numRead = fis.read(buffer); DigestInputStream dis = new DigestInputStream(bis, digest);
if (numRead > 0) { //yes, we are reading in a buffer for performance reasons - 1 byte at a time is SLOW
complete.update(buffer, 0, numRead); byte[] buffer = new byte[8192];
} while (dis.read(buffer) != -1);
} while (numRead != -1);
} finally { } finally {
if (fis != null) { if (fis != null) {
try { try {
@@ -65,7 +76,7 @@ public final class Checksum {
} }
} }
} }
return complete.digest(); return digest.digest();
} }
/** /**
@@ -93,12 +104,17 @@ public final class Checksum {
byte[] b = getChecksum("SHA1", file); byte[] b = getChecksum("SHA1", file);
return getHex(b); return getHex(b);
} }
/**
* Hex code characters used in getHex.
*/
private static final String HEXES = "0123456789ABCDEF"; private static final String HEXES = "0123456789ABCDEF";
/** /**
* <p>Converts a byte array into a hex string.</p> * <p>
* Converts a byte array into a hex string.</p>
* *
* <p>This method was copied from <a * <p>
* This method was copied from <a
* href="http://www.rgagnon.com/javadetails/java-0596.html">http://www.rgagnon.com/javadetails/java-0596.html</a></p> * href="http://www.rgagnon.com/javadetails/java-0596.html">http://www.rgagnon.com/javadetails/java-0596.html</a></p>
* *
* @param raw a byte array * @param raw a byte array