View Javadoc
1   /*
2    * This file is part of dependency-check-core.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   *
16   * Copyright (c) 2014 Jeremy Long. All Rights Reserved.
17   */
18  package org.owasp.dependencycheck.utils;
19  
20  import java.io.File;
21  import java.io.FileInputStream;
22  import java.io.IOException;
23  import java.nio.MappedByteBuffer;
24  import java.nio.channels.FileChannel;
25  import java.security.MessageDigest;
26  import java.security.NoSuchAlgorithmException;
27  import java.util.logging.Level;
28  import java.util.logging.Logger;
29  
30  /**
31   * Includes methods to generate the MD5 and SHA1 checksum.
32   *
33   * @author Jeremy Long <jeremy.long@owasp.org>
34   *
35   */
36  public final class Checksum {
37  
38      /**
39       * The logger.
40       */
41      private static final Logger LOGGER = Logger.getLogger(Checksum.class.getName());
42  
43      /**
44       * Private constructor for a utility class.
45       */
46      private Checksum() {
47      }
48  
49      /**
50       * <p>
51       * Creates the cryptographic checksum of a given file using the specified algorithm.</p>
52       *
53       * @param algorithm the algorithm to use to calculate the checksum
54       * @param file the file to calculate the checksum for
55       * @return the checksum
56       * @throws IOException when the file does not exist
57       * @throws NoSuchAlgorithmException when an algorithm is specified that does not exist
58       */
59      @SuppressWarnings("empty-statement")
60      public static byte[] getChecksum(String algorithm, File file) throws NoSuchAlgorithmException, IOException {
61          MessageDigest digest = MessageDigest.getInstance(algorithm);
62          FileInputStream fis = null;
63          try {
64              fis = new FileInputStream(file);
65              FileChannel ch = fis.getChannel();
66              MappedByteBuffer byteBuffer = ch.map(FileChannel.MapMode.READ_ONLY, 0, file.length());
67              digest.update(byteBuffer);
68  //            BufferedInputStream bis = new BufferedInputStream(fis);
69  //            DigestInputStream dis = new DigestInputStream(bis, digest);
70  //            //yes, we are reading in a buffer for performance reasons - 1 byte at a time is SLOW
71  //            byte[] buffer = new byte[8192];
72  //            while (dis.read(buffer) != -1);
73          } finally {
74              if (fis != null) {
75                  try {
76                      fis.close();
77                  } catch (IOException ex) {
78                      LOGGER.log(Level.FINEST, "Error closing file '" + file.getName() + "'.", ex);
79                  }
80              }
81          }
82          return digest.digest();
83      }
84  
85      /**
86       * Calculates the MD5 checksum of a specified file.
87       *
88       * @param file the file to generate the MD5 checksum
89       * @return the hex representation of the MD5 hash
90       * @throws IOException when the file passed in does not exist
91       * @throws NoSuchAlgorithmException when the MD5 algorithm is not available
92       */
93      public static String getMD5Checksum(File file) throws IOException, NoSuchAlgorithmException {
94          byte[] b = getChecksum("MD5", file);
95          return getHex(b);
96      }
97  
98      /**
99       * Calculates the SHA1 checksum of a specified file.
100      *
101      * @param file the file to generate the MD5 checksum
102      * @return the hex representation of the SHA1 hash
103      * @throws IOException when the file passed in does not exist
104      * @throws NoSuchAlgorithmException when the SHA1 algorithm is not available
105      */
106     public static String getSHA1Checksum(File file) throws IOException, NoSuchAlgorithmException {
107         byte[] b = getChecksum("SHA1", file);
108         return getHex(b);
109     }
110     /**
111      * Hex code characters used in getHex.
112      */
113     private static final String HEXES = "0123456789ABCDEF";
114 
115     /**
116      * <p>
117      * Converts a byte array into a hex string.</p>
118      *
119      * <p>
120      * This method was copied from <a
121      * href="http://www.rgagnon.com/javadetails/java-0596.html">http://www.rgagnon.com/javadetails/java-0596.html</a></p>
122      *
123      * @param raw a byte array
124      * @return the hex representation of the byte array
125      */
126     public static String getHex(byte[] raw) {
127         if (raw == null) {
128             return null;
129         }
130         final StringBuilder hex = new StringBuilder(2 * raw.length);
131         for (final byte b : raw) {
132             hex.append(HEXES.charAt((b & 0xF0) >> 4)).append(HEXES.charAt(b & 0x0F));
133         }
134         return hex.toString();
135     }
136 }