<commit_before>package org.owasp.dependencycheck.utils;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Includes methods to generate the MD5 and SHA1 checksum.
 *
 * This code was copied from Real's How To. It has been slightly modified.
 *
 * Written and compiled by <NAME> ©1998-2012
 *
 * @author Real's How To: http://www.rgagnon.com/javadetails/java-0416.html
 *
 */
public final class Checksum {
    
    /**
     * The logger.
     */
    private static final Logger LOGGER = Logger.getLogger(Checksum.class.getName());
    /**
     * Private constructor for a utility class.
     */
    private Checksum() {
    }

    /**
     * <p>Creates the cryptographic checksum of a given file using the specified
     * algorithm.</p> <p>This algorithm was copied and heavily modified from
     * Real's How To: http://www.rgagnon.com/javadetails/java-0416.html</p>
     *
     * @param algorithm the algorithm to use to calculate the checksum
     * @param file the file to calculate the checksum for
     * @return the checksum
     * @throws IOException when the file does not exist
     * @throws NoSuchAlgorithmException when an algorithm is specified that does
     * not exist
     */
    public static byte[] getChecksum(String algorithm, File file) throws NoSuchAlgorithmException, IOException {
        InputStream fis = null;
        byte[] buffer = new byte[1024];
        MessageDigest complete = MessageDigest.getInstance(algorithm);
        int numRead;
        try {
            fis = new FileInputStream(file);
            do {
                numRead = fis.read(buffer);
                if (numRead > 0) {
                    complete.update(buffer, 0, numRead);
                }
            } while (numRead != -1);
        } finally {
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException ex) {
                    LOGGER.log(Level.FINEST, "Error closing file '" + file.getName() + "'.", ex);
                }
            }
        }
        return complete.digest();
    }

    /**
     * Calculates the MD5 checksum of a specified file.
     *
     * @param file the file to generate the MD5 checksum
     * @return the hex representation of the MD5 hash
     * @throws IOException when the file passed in does not exist
     * @throws NoSuchAlgorithmException when the MD5 algorithm is not available
     */
    public static String getMD5Checksum(File file) throws IOException, NoSuchAlgorithmException {
        byte[] b = getChecksum("MD5", file);
        return getHex(b);
    }

    /**
     * Calculates the SHA1 checksum of a specified file.
     *
     * @param file the file to generate the MD5 checksum
     * @return the hex representation of the SHA1 hash
     * @throws IOException when the file passed in does not exist
     * @throws NoSuchAlgorithmException when the SHA1 algorithm is not available
     */
    public static String getSHA1Checksum(File file) throws IOException, NoSuchAlgorithmException {
        byte[] b = getChecksum("SHA1", file);
        return getHex(b);
    }
    private static final String HEXES = "0123456789ABCDEF";

    /**
     * <p>Converts a byte array into a hex string.</p>
     *
     * <p>This method was copied from <a<commit_msg>performance improvements for large files<commit_after>/*
 * 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 <NAME>. All Rights Reserved.
 */
package org.owasp.dependencycheck.utils;

import java.io.BufferedInputStream;
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.logging.Level;
import java.util.logging.Logger;

/**
 * Includes methods to generate the MD5 and SHA1 checksum.
 *
 * @author <NAME> <<EMAIL>>
 *
 */
public final class Checksum {

    /**
     * The logger.
     */
    private static final Logger LOGGER = Logger.getLogger(Checksum.class.getName());

    /**
     * Private constructor for a utility class.
     */
    private Checksum() {
    }

    /**
     * <p>
     * Creates the cryptographic checksum of a given file using the specified algorithm.</p>
     *
     * @param algorithm the algorithm to use to calculate the checksum
     * @param file the file to calculate the checksum for
     * @return the checksum
     * @throws IOException when the file does not exist
     * @throws NoSuchAlgorithmException when an algorithm is specified that does not exist
     */
    public static byte[] getChecksum(String algorithm, File file) throws NoSuchAlgorithmException, IOException {
        MessageDigest digest = MessageDigest.getInstance(algorithm);
        InputStream fis = null;
        try {
            fis = new FileInputStream(file);
            BufferedInputStream bis = new BufferedInputStream(fis);
            DigestInputStream dis = new DigestInputStream(bis, digest);
            //yes, we are reading in a buffer for performance reasons - 1 byte at a time is SLOW
            byte[] buffer = new byte[8192];
            while (dis.read(buffer) != -1);
        } finally {
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException ex) {
                    LOGGER.log(Level.FINEST, "Error closing file '" + file.getName() + "'.", ex);
                }
            }
        }
        return digest.digest();
    }

    /**
     * Calculates the MD5 checksum of a specified file.
     *
     * @param file the file to generate the MD5 checksum
     * @return the hex representation of the MD5 hash
     * @throws IOException when the file passed in does not exist
     * @throws NoSuchAlgorithmException when the MD5 algorithm is not available
     */
    public static String getMD5Checksum(File file) throws IOException, NoSuchAlgorithmException {
        byte[] b = getChecksum("MD5", file);
        return getHex(b);
    }

    /**
     * Calculates the SHA1 checksum of a specified file.
     *
     * @param file the file to generate the MD5 checksum
     * @return the hex representation of the SHA1 hash
     * @throws IOException when the file passed in does not exist
     * @throws NoSuchAlgorithmException when the SHA1 algorithm is not available
     */
    public static String getSHA1Checksum(File file) throws IOException, NoSuchAlgorithmException {
        byte[] b = getChecksum("SHA1", file);
        return getHex(b);
    }
    /**
     * Hex code characters used in getHex.
     */
    private static final String HEXES = "0123456789ABCDEF";

    /**
     * <p>
     * Converts a byte array into a hex string.</p>
     *
     * <p>
     * This method was copied from <a
{'fraction_non_alphanumeric': 0.0869220607661823, 'fraction_numerical': 0.011228533685601057, 'mean_word_length': 2.471343420449335, 'pattern_counts': {'":': 0, '<': 22, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 3, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4743935', 'n_tokens_mistral': 2055, 'n_tokens_neox': 2001, 'n_words': 744}