DigestUtils.java

  1. /*
  2.  * Licensed to the Apache Software Foundation (ASF) under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * The ASF licenses this file to You under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  *      http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */

  17. package org.apache.commons.codec.digest;

  18. import java.io.BufferedInputStream;
  19. import java.io.File;
  20. import java.io.FileInputStream;
  21. import java.io.IOException;
  22. import java.io.InputStream;
  23. import java.nio.ByteBuffer;
  24. import java.security.MessageDigest;
  25. import java.security.NoSuchAlgorithmException;

  26. import org.apache.commons.codec.binary.Hex;
  27. import org.apache.commons.codec.binary.StringUtils;

  28. /**
  29.  * Operations to simplify common {@link java.security.MessageDigest} tasks.
  30.  * This class is immutable and thread-safe.
  31.  * However the MessageDigest instances it creates generally won't be.
  32.  * <p>
  33.  * The {@link MessageDigestAlgorithms} class provides constants for standard
  34.  * digest algorithms that can be used with the {@link #getDigest(String)} method
  35.  * and other methods that require the Digest algorithm name.
  36.  * <p>
  37.  * Note: the class has short-hand methods for all the algorithms present as standard in Java 6.
  38.  * This approach requires lots of methods for each algorithm, and quickly becomes unwieldy.
  39.  * The following code works with all algorithms:
  40.  * <pre>
  41.  * import static org.apache.commons.codec.digest.MessageDigestAlgorithms.SHA_224;
  42.  * ...
  43.  * byte [] digest = new DigestUtils(SHA_224).digest(dataToDigest);
  44.  * String hdigest = new DigestUtils(SHA_224).digestAsHex(new File("pom.xml"));
  45.  * </pre>
  46.  * @see MessageDigestAlgorithms
  47.  * @version $Id: DigestUtils.java 1811344 2017-10-06 15:19:57Z ggregory $
  48.  */
  49. public class DigestUtils {

  50.     private static final int STREAM_BUFFER_LENGTH = 1024;

  51.     /**
  52.      * Reads through a byte array and returns the digest for the data. Provided for symmetry with other methods.
  53.      *
  54.      * @param messageDigest
  55.      *            The MessageDigest to use (e.g. MD5)
  56.      * @param data
  57.      *            Data to digest
  58.      * @return the digest
  59.      * @since 1.11
  60.      */
  61.     public static byte[] digest(final MessageDigest messageDigest, final byte[] data) {
  62.         return messageDigest.digest(data);
  63.     }

  64.     /**
  65.      * Reads through a ByteBuffer and returns the digest for the data
  66.      *
  67.      * @param messageDigest
  68.      *            The MessageDigest to use (e.g. MD5)
  69.      * @param data
  70.      *            Data to digest
  71.      * @return the digest
  72.      *
  73.      * @since 1.11
  74.      */
  75.     public static byte[] digest(final MessageDigest messageDigest, final ByteBuffer data) {
  76.         messageDigest.update(data);
  77.         return messageDigest.digest();
  78.     }

  79.     /**
  80.      * Reads through a File and returns the digest for the data
  81.      *
  82.      * @param messageDigest
  83.      *            The MessageDigest to use (e.g. MD5)
  84.      * @param data
  85.      *            Data to digest
  86.      * @return the digest
  87.      * @throws IOException
  88.      *             On error reading from the stream
  89.      * @since 1.11
  90.      */
  91.     public static byte[] digest(final MessageDigest messageDigest, final File data) throws IOException {
  92.         return updateDigest(messageDigest, data).digest();
  93.     }

  94.     /**
  95.      * Reads through an InputStream and returns the digest for the data
  96.      *
  97.      * @param messageDigest
  98.      *            The MessageDigest to use (e.g. MD5)
  99.      * @param data
  100.      *            Data to digest
  101.      * @return the digest
  102.      * @throws IOException
  103.      *             On error reading from the stream
  104.      * @since 1.11 (was private)
  105.      */
  106.     public static byte[] digest(final MessageDigest messageDigest, final InputStream data) throws IOException {
  107.         return updateDigest(messageDigest, data).digest();
  108.     }

  109.     /**
  110.      * Returns a <code>MessageDigest</code> for the given <code>algorithm</code>.
  111.      *
  112.      * @param algorithm
  113.      *            the name of the algorithm requested. See <a
  114.      *            href="http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA"
  115.      *            >Appendix A in the Java Cryptography Architecture Reference Guide</a> for information about standard
  116.      *            algorithm names.
  117.      * @return A digest instance.
  118.      * @see MessageDigest#getInstance(String)
  119.      * @throws IllegalArgumentException
  120.      *             when a {@link NoSuchAlgorithmException} is caught.
  121.      */
  122.     public static MessageDigest getDigest(final String algorithm) {
  123.         try {
  124.             return MessageDigest.getInstance(algorithm);
  125.         } catch (final NoSuchAlgorithmException e) {
  126.             throw new IllegalArgumentException(e);
  127.         }
  128.     }

  129.     /**
  130.      * Returns a <code>MessageDigest</code> for the given <code>algorithm</code> or a default if there is a problem
  131.      * getting the algorithm.
  132.      *
  133.      * @param algorithm
  134.      *            the name of the algorithm requested. See
  135.      *            <a href="http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA" >
  136.      *            Appendix A in the Java Cryptography Architecture Reference Guide</a> for information about standard
  137.      *            algorithm names.
  138.      * @param defaultMessageDigest
  139.      *            The default MessageDigest.
  140.      * @return A digest instance.
  141.      * @see MessageDigest#getInstance(String)
  142.      * @throws IllegalArgumentException
  143.      *             when a {@link NoSuchAlgorithmException} is caught.
  144.      * @since 1.11
  145.      */
  146.     public static MessageDigest getDigest(final String algorithm, final MessageDigest defaultMessageDigest) {
  147.         try {
  148.             return MessageDigest.getInstance(algorithm);
  149.         } catch (final Exception e) {
  150.             return defaultMessageDigest;
  151.         }
  152.     }

  153.     /**
  154.      * Returns an MD2 MessageDigest.
  155.      *
  156.      * @return An MD2 digest instance.
  157.      * @throws IllegalArgumentException
  158.      *             when a {@link NoSuchAlgorithmException} is caught, which should never happen because MD2 is a
  159.      *             built-in algorithm
  160.      * @see MessageDigestAlgorithms#MD2
  161.      * @since 1.7
  162.      */
  163.     public static MessageDigest getMd2Digest() {
  164.         return getDigest(MessageDigestAlgorithms.MD2);
  165.     }

  166.     /**
  167.      * Returns an MD5 MessageDigest.
  168.      *
  169.      * @return An MD5 digest instance.
  170.      * @throws IllegalArgumentException
  171.      *             when a {@link NoSuchAlgorithmException} is caught, which should never happen because MD5 is a
  172.      *             built-in algorithm
  173.      * @see MessageDigestAlgorithms#MD5
  174.      */
  175.     public static MessageDigest getMd5Digest() {
  176.         return getDigest(MessageDigestAlgorithms.MD5);
  177.     }

  178.     /**
  179.      * Returns an SHA-1 digest.
  180.      *
  181.      * @return An SHA-1 digest instance.
  182.      * @throws IllegalArgumentException
  183.      *             when a {@link NoSuchAlgorithmException} is caught, which should never happen because SHA-1 is a
  184.      *             built-in algorithm
  185.      * @see MessageDigestAlgorithms#SHA_1
  186.      * @since 1.7
  187.      */
  188.     public static MessageDigest getSha1Digest() {
  189.         return getDigest(MessageDigestAlgorithms.SHA_1);
  190.     }

  191.     /**
  192.      * Returns an SHA-256 digest.
  193.      * <p>
  194.      * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
  195.      * </p>
  196.      *
  197.      * @return An SHA-256 digest instance.
  198.      * @throws IllegalArgumentException
  199.      *             when a {@link NoSuchAlgorithmException} is caught, which should never happen because SHA-256 is a
  200.      *             built-in algorithm
  201.      * @see MessageDigestAlgorithms#SHA_256
  202.      */
  203.     public static MessageDigest getSha256Digest() {
  204.         return getDigest(MessageDigestAlgorithms.SHA_256);
  205.     }

  206.     /**
  207.      * Returns an SHA-384 digest.
  208.      * <p>
  209.      * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
  210.      * </p>
  211.      *
  212.      * @return An SHA-384 digest instance.
  213.      * @throws IllegalArgumentException
  214.      *             when a {@link NoSuchAlgorithmException} is caught, which should never happen because SHA-384 is a
  215.      *             built-in algorithm
  216.      * @see MessageDigestAlgorithms#SHA_384
  217.      */
  218.     public static MessageDigest getSha384Digest() {
  219.         return getDigest(MessageDigestAlgorithms.SHA_384);
  220.     }

  221.     /**
  222.      * Returns an SHA-512 digest.
  223.      * <p>
  224.      * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
  225.      * </p>
  226.      *
  227.      * @return An SHA-512 digest instance.
  228.      * @throws IllegalArgumentException
  229.      *             when a {@link NoSuchAlgorithmException} is caught, which should never happen because SHA-512 is a
  230.      *             built-in algorithm
  231.      * @see MessageDigestAlgorithms#SHA_512
  232.      */
  233.     public static MessageDigest getSha512Digest() {
  234.         return getDigest(MessageDigestAlgorithms.SHA_512);
  235.     }

  236.     /**
  237.      * Returns an SHA-1 digest.
  238.      *
  239.      * @return An SHA-1 digest instance.
  240.      * @throws IllegalArgumentException
  241.      *             when a {@link NoSuchAlgorithmException} is caught
  242.      * @deprecated (1.11) Use {@link #getSha1Digest()}
  243.      */
  244.     @Deprecated
  245.     public static MessageDigest getShaDigest() {
  246.         return getSha1Digest();
  247.     }

  248.     /**
  249.      * Calculates the MD2 digest and returns the value as a 16 element <code>byte[]</code>.
  250.      *
  251.      * @param data
  252.      *            Data to digest
  253.      * @return MD2 digest
  254.      * @since 1.7
  255.      */
  256.     public static byte[] md2(final byte[] data) {
  257.         return getMd2Digest().digest(data);
  258.     }

  259.     /**
  260.      * Calculates the MD2 digest and returns the value as a 16 element <code>byte[]</code>.
  261.      *
  262.      * @param data
  263.      *            Data to digest
  264.      * @return MD2 digest
  265.      * @throws IOException
  266.      *             On error reading from the stream
  267.      * @since 1.7
  268.      */
  269.     public static byte[] md2(final InputStream data) throws IOException {
  270.         return digest(getMd2Digest(), data);
  271.     }

  272.     /**
  273.      * Calculates the MD2 digest and returns the value as a 16 element <code>byte[]</code>.
  274.      *
  275.      * @param data
  276.      *            Data to digest; converted to bytes using {@link StringUtils#getBytesUtf8(String)}
  277.      * @return MD2 digest
  278.      * @since 1.7
  279.      */
  280.     public static byte[] md2(final String data) {
  281.         return md2(StringUtils.getBytesUtf8(data));
  282.     }

  283.     /**
  284.      * Calculates the MD2 digest and returns the value as a 32 character hex string.
  285.      *
  286.      * @param data
  287.      *            Data to digest
  288.      * @return MD2 digest as a hex string
  289.      * @since 1.7
  290.      */
  291.     public static String md2Hex(final byte[] data) {
  292.         return Hex.encodeHexString(md2(data));
  293.     }

  294.     /**
  295.      * Calculates the MD2 digest and returns the value as a 32 character hex string.
  296.      *
  297.      * @param data
  298.      *            Data to digest
  299.      * @return MD2 digest as a hex string
  300.      * @throws IOException
  301.      *             On error reading from the stream
  302.      * @since 1.7
  303.      */
  304.     public static String md2Hex(final InputStream data) throws IOException {
  305.         return Hex.encodeHexString(md2(data));
  306.     }

  307.     /**
  308.      * Calculates the MD2 digest and returns the value as a 32 character hex string.
  309.      *
  310.      * @param data
  311.      *            Data to digest
  312.      * @return MD2 digest as a hex string
  313.      * @since 1.7
  314.      */
  315.     public static String md2Hex(final String data) {
  316.         return Hex.encodeHexString(md2(data));
  317.     }

  318.     /**
  319.      * Calculates the MD5 digest and returns the value as a 16 element <code>byte[]</code>.
  320.      *
  321.      * @param data
  322.      *            Data to digest
  323.      * @return MD5 digest
  324.      */
  325.     public static byte[] md5(final byte[] data) {
  326.         return getMd5Digest().digest(data);
  327.     }

  328.     /**
  329.      * Calculates the MD5 digest and returns the value as a 16 element <code>byte[]</code>.
  330.      *
  331.      * @param data
  332.      *            Data to digest
  333.      * @return MD5 digest
  334.      * @throws IOException
  335.      *             On error reading from the stream
  336.      * @since 1.4
  337.      */
  338.     public static byte[] md5(final InputStream data) throws IOException {
  339.         return digest(getMd5Digest(), data);
  340.     }

  341.     /**
  342.      * Calculates the MD5 digest and returns the value as a 16 element <code>byte[]</code>.
  343.      *
  344.      * @param data
  345.      *            Data to digest; converted to bytes using {@link StringUtils#getBytesUtf8(String)}
  346.      * @return MD5 digest
  347.      */
  348.     public static byte[] md5(final String data) {
  349.         return md5(StringUtils.getBytesUtf8(data));
  350.     }

  351.     /**
  352.      * Calculates the MD5 digest and returns the value as a 32 character hex string.
  353.      *
  354.      * @param data
  355.      *            Data to digest
  356.      * @return MD5 digest as a hex string
  357.      */
  358.     public static String md5Hex(final byte[] data) {
  359.         return Hex.encodeHexString(md5(data));
  360.     }

  361.     /**
  362.      * Calculates the MD5 digest and returns the value as a 32 character hex string.
  363.      *
  364.      * @param data
  365.      *            Data to digest
  366.      * @return MD5 digest as a hex string
  367.      * @throws IOException
  368.      *             On error reading from the stream
  369.      * @since 1.4
  370.      */
  371.     public static String md5Hex(final InputStream data) throws IOException {
  372.         return Hex.encodeHexString(md5(data));
  373.     }

  374.     /**
  375.      * Calculates the MD5 digest and returns the value as a 32 character hex string.
  376.      *
  377.      * @param data
  378.      *            Data to digest
  379.      * @return MD5 digest as a hex string
  380.      */
  381.     public static String md5Hex(final String data) {
  382.         return Hex.encodeHexString(md5(data));
  383.     }

  384.     /**
  385.      * Calculates the SHA-1 digest and returns the value as a <code>byte[]</code>.
  386.      *
  387.      * @param data
  388.      *            Data to digest
  389.      * @return SHA-1 digest
  390.      * @deprecated (1.11) Use {@link #sha1(byte[])}
  391.      */
  392.     @Deprecated
  393.     public static byte[] sha(final byte[] data) {
  394.         return sha1(data);
  395.     }

  396.     /**
  397.      * Calculates the SHA-1 digest and returns the value as a <code>byte[]</code>.
  398.      *
  399.      * @param data
  400.      *            Data to digest
  401.      * @return SHA-1 digest
  402.      * @throws IOException
  403.      *             On error reading from the stream
  404.      * @since 1.4
  405.      * @deprecated (1.11) Use {@link #sha1(InputStream)}
  406.      */
  407.     @Deprecated
  408.     public static byte[] sha(final InputStream data) throws IOException {
  409.         return sha1(data);
  410.     }

  411.     /**
  412.      * Calculates the SHA-1 digest and returns the value as a <code>byte[]</code>.
  413.      *
  414.      * @param data
  415.      *            Data to digest
  416.      * @return SHA-1 digest
  417.      * @deprecated (1.11) Use {@link #sha1(String)}
  418.      */
  419.     @Deprecated
  420.     public static byte[] sha(final String data) {
  421.         return sha1(data);
  422.     }

  423.     /**
  424.      * Calculates the SHA-1 digest and returns the value as a <code>byte[]</code>.
  425.      *
  426.      * @param data
  427.      *            Data to digest
  428.      * @return SHA-1 digest
  429.      * @since 1.7
  430.      */
  431.     public static byte[] sha1(final byte[] data) {
  432.         return getSha1Digest().digest(data);
  433.     }

  434.     /**
  435.      * Calculates the SHA-1 digest and returns the value as a <code>byte[]</code>.
  436.      *
  437.      * @param data
  438.      *            Data to digest
  439.      * @return SHA-1 digest
  440.      * @throws IOException
  441.      *             On error reading from the stream
  442.      * @since 1.7
  443.      */
  444.     public static byte[] sha1(final InputStream data) throws IOException {
  445.         return digest(getSha1Digest(), data);
  446.     }

  447.     /**
  448.      * Calculates the SHA-1 digest and returns the value as a <code>byte[]</code>.
  449.      *
  450.      * @param data
  451.      *            Data to digest; converted to bytes using {@link StringUtils#getBytesUtf8(String)}
  452.      * @return SHA-1 digest
  453.      */
  454.     public static byte[] sha1(final String data) {
  455.         return sha1(StringUtils.getBytesUtf8(data));
  456.     }

  457.     /**
  458.      * Calculates the SHA-1 digest and returns the value as a hex string.
  459.      *
  460.      * @param data
  461.      *            Data to digest
  462.      * @return SHA-1 digest as a hex string
  463.      * @since 1.7
  464.      */
  465.     public static String sha1Hex(final byte[] data) {
  466.         return Hex.encodeHexString(sha1(data));
  467.     }

  468.     /**
  469.      * Calculates the SHA-1 digest and returns the value as a hex string.
  470.      *
  471.      * @param data
  472.      *            Data to digest
  473.      * @return SHA-1 digest as a hex string
  474.      * @throws IOException
  475.      *             On error reading from the stream
  476.      * @since 1.7
  477.      */
  478.     public static String sha1Hex(final InputStream data) throws IOException {
  479.         return Hex.encodeHexString(sha1(data));
  480.     }

  481.     /**
  482.      * Calculates the SHA-1 digest and returns the value as a hex string.
  483.      *
  484.      * @param data
  485.      *            Data to digest
  486.      * @return SHA-1 digest as a hex string
  487.      * @since 1.7
  488.      */
  489.     public static String sha1Hex(final String data) {
  490.         return Hex.encodeHexString(sha1(data));
  491.     }

  492.     /**
  493.      * Calculates the SHA-256 digest and returns the value as a <code>byte[]</code>.
  494.      * <p>
  495.      * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
  496.      * </p>
  497.      *
  498.      * @param data
  499.      *            Data to digest
  500.      * @return SHA-256 digest
  501.      * @since 1.4
  502.      */
  503.     public static byte[] sha256(final byte[] data) {
  504.         return getSha256Digest().digest(data);
  505.     }

  506.     /**
  507.      * Calculates the SHA-256 digest and returns the value as a <code>byte[]</code>.
  508.      * <p>
  509.      * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
  510.      * </p>
  511.      *
  512.      * @param data
  513.      *            Data to digest
  514.      * @return SHA-256 digest
  515.      * @throws IOException
  516.      *             On error reading from the stream
  517.      * @since 1.4
  518.      */
  519.     public static byte[] sha256(final InputStream data) throws IOException {
  520.         return digest(getSha256Digest(), data);
  521.     }

  522.     /**
  523.      * Calculates the SHA-256 digest and returns the value as a <code>byte[]</code>.
  524.      * <p>
  525.      * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
  526.      * </p>
  527.      *
  528.      * @param data
  529.      *            Data to digest; converted to bytes using {@link StringUtils#getBytesUtf8(String)}
  530.      * @return SHA-256 digest
  531.      * @since 1.4
  532.      */
  533.     public static byte[] sha256(final String data) {
  534.         return sha256(StringUtils.getBytesUtf8(data));
  535.     }

  536.     /**
  537.      * Calculates the SHA-256 digest and returns the value as a hex string.
  538.      * <p>
  539.      * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
  540.      * </p>
  541.      *
  542.      * @param data
  543.      *            Data to digest
  544.      * @return SHA-256 digest as a hex string
  545.      * @since 1.4
  546.      */
  547.     public static String sha256Hex(final byte[] data) {
  548.         return Hex.encodeHexString(sha256(data));
  549.     }

  550.     /**
  551.      * Calculates the SHA-256 digest and returns the value as a hex string.
  552.      * <p>
  553.      * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
  554.      * </p>
  555.      *
  556.      * @param data
  557.      *            Data to digest
  558.      * @return SHA-256 digest as a hex string
  559.      * @throws IOException
  560.      *             On error reading from the stream
  561.      * @since 1.4
  562.      */
  563.     public static String sha256Hex(final InputStream data) throws IOException {
  564.         return Hex.encodeHexString(sha256(data));
  565.     }

  566.     /**
  567.      * Calculates the SHA-256 digest and returns the value as a hex string.
  568.      * <p>
  569.      * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
  570.      * </p>
  571.      *
  572.      * @param data
  573.      *            Data to digest
  574.      * @return SHA-256 digest as a hex string
  575.      * @since 1.4
  576.      */
  577.     public static String sha256Hex(final String data) {
  578.         return Hex.encodeHexString(sha256(data));
  579.     }

  580.     /**
  581.      * Calculates the SHA-384 digest and returns the value as a <code>byte[]</code>.
  582.      * <p>
  583.      * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
  584.      * </p>
  585.      *
  586.      * @param data
  587.      *            Data to digest
  588.      * @return SHA-384 digest
  589.      * @since 1.4
  590.      */
  591.     public static byte[] sha384(final byte[] data) {
  592.         return getSha384Digest().digest(data);
  593.     }

  594.     /**
  595.      * Calculates the SHA-384 digest and returns the value as a <code>byte[]</code>.
  596.      * <p>
  597.      * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
  598.      * </p>
  599.      *
  600.      * @param data
  601.      *            Data to digest
  602.      * @return SHA-384 digest
  603.      * @throws IOException
  604.      *             On error reading from the stream
  605.      * @since 1.4
  606.      */
  607.     public static byte[] sha384(final InputStream data) throws IOException {
  608.         return digest(getSha384Digest(), data);
  609.     }

  610.     /**
  611.      * Calculates the SHA-384 digest and returns the value as a <code>byte[]</code>.
  612.      * <p>
  613.      * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
  614.      * </p>
  615.      *
  616.      * @param data
  617.      *            Data to digest; converted to bytes using {@link StringUtils#getBytesUtf8(String)}
  618.      * @return SHA-384 digest
  619.      * @since 1.4
  620.      */
  621.     public static byte[] sha384(final String data) {
  622.         return sha384(StringUtils.getBytesUtf8(data));
  623.     }

  624.     /**
  625.      * Calculates the SHA-384 digest and returns the value as a hex string.
  626.      * <p>
  627.      * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
  628.      * </p>
  629.      *
  630.      * @param data
  631.      *            Data to digest
  632.      * @return SHA-384 digest as a hex string
  633.      * @since 1.4
  634.      */
  635.     public static String sha384Hex(final byte[] data) {
  636.         return Hex.encodeHexString(sha384(data));
  637.     }

  638.     /**
  639.      * Calculates the SHA-384 digest and returns the value as a hex string.
  640.      * <p>
  641.      * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
  642.      * </p>
  643.      *
  644.      * @param data
  645.      *            Data to digest
  646.      * @return SHA-384 digest as a hex string
  647.      * @throws IOException
  648.      *             On error reading from the stream
  649.      * @since 1.4
  650.      */
  651.     public static String sha384Hex(final InputStream data) throws IOException {
  652.         return Hex.encodeHexString(sha384(data));
  653.     }

  654.     /**
  655.      * Calculates the SHA-384 digest and returns the value as a hex string.
  656.      * <p>
  657.      * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
  658.      * </p>
  659.      *
  660.      * @param data
  661.      *            Data to digest
  662.      * @return SHA-384 digest as a hex string
  663.      * @since 1.4
  664.      */
  665.     public static String sha384Hex(final String data) {
  666.         return Hex.encodeHexString(sha384(data));
  667.     }

  668.     /**
  669.      * Calculates the SHA-512 digest and returns the value as a <code>byte[]</code>.
  670.      * <p>
  671.      * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
  672.      * </p>
  673.      *
  674.      * @param data
  675.      *            Data to digest
  676.      * @return SHA-512 digest
  677.      * @since 1.4
  678.      */
  679.     public static byte[] sha512(final byte[] data) {
  680.         return getSha512Digest().digest(data);
  681.     }

  682.     /**
  683.      * Calculates the SHA-512 digest and returns the value as a <code>byte[]</code>.
  684.      * <p>
  685.      * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
  686.      * </p>
  687.      *
  688.      * @param data
  689.      *            Data to digest
  690.      * @return SHA-512 digest
  691.      * @throws IOException
  692.      *             On error reading from the stream
  693.      * @since 1.4
  694.      */
  695.     public static byte[] sha512(final InputStream data) throws IOException {
  696.         return digest(getSha512Digest(), data);
  697.     }

  698.     /**
  699.      * Calculates the SHA-512 digest and returns the value as a <code>byte[]</code>.
  700.      * <p>
  701.      * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
  702.      * </p>
  703.      *
  704.      * @param data
  705.      *            Data to digest; converted to bytes using {@link StringUtils#getBytesUtf8(String)}
  706.      * @return SHA-512 digest
  707.      * @since 1.4
  708.      */
  709.     public static byte[] sha512(final String data) {
  710.         return sha512(StringUtils.getBytesUtf8(data));
  711.     }

  712.     /**
  713.      * Calculates the SHA-512 digest and returns the value as a hex string.
  714.      * <p>
  715.      * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
  716.      * </p>
  717.      *
  718.      * @param data
  719.      *            Data to digest
  720.      * @return SHA-512 digest as a hex string
  721.      * @since 1.4
  722.      */
  723.     public static String sha512Hex(final byte[] data) {
  724.         return Hex.encodeHexString(sha512(data));
  725.     }

  726.     /**
  727.      * Calculates the SHA-512 digest and returns the value as a hex string.
  728.      * <p>
  729.      * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
  730.      * </p>
  731.      *
  732.      * @param data
  733.      *            Data to digest
  734.      * @return SHA-512 digest as a hex string
  735.      * @throws IOException
  736.      *             On error reading from the stream
  737.      * @since 1.4
  738.      */
  739.     public static String sha512Hex(final InputStream data) throws IOException {
  740.         return Hex.encodeHexString(sha512(data));
  741.     }

  742.     /**
  743.      * Calculates the SHA-512 digest and returns the value as a hex string.
  744.      * <p>
  745.      * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
  746.      * </p>
  747.      *
  748.      * @param data
  749.      *            Data to digest
  750.      * @return SHA-512 digest as a hex string
  751.      * @since 1.4
  752.      */
  753.     public static String sha512Hex(final String data) {
  754.         return Hex.encodeHexString(sha512(data));
  755.     }

  756.     /**
  757.      * Calculates the SHA-1 digest and returns the value as a hex string.
  758.      *
  759.      * @param data
  760.      *            Data to digest
  761.      * @return SHA-1 digest as a hex string
  762.      * @deprecated (1.11) Use {@link #sha1Hex(byte[])}
  763.      */
  764.     @Deprecated
  765.     public static String shaHex(final byte[] data) {
  766.         return sha1Hex(data);
  767.     }

  768.     /**
  769.      * Calculates the SHA-1 digest and returns the value as a hex string.
  770.      *
  771.      * @param data
  772.      *            Data to digest
  773.      * @return SHA-1 digest as a hex string
  774.      * @throws IOException
  775.      *             On error reading from the stream
  776.      * @since 1.4
  777.      * @deprecated (1.11) Use {@link #sha1Hex(InputStream)}
  778.      */
  779.     @Deprecated
  780.     public static String shaHex(final InputStream data) throws IOException {
  781.         return sha1Hex(data);
  782.     }

  783.     /**
  784.      * Calculates the SHA-1 digest and returns the value as a hex string.
  785.      *
  786.      * @param data
  787.      *            Data to digest
  788.      * @return SHA-1 digest as a hex string
  789.      * @deprecated (1.11) Use {@link #sha1Hex(String)}
  790.      */
  791.     @Deprecated
  792.     public static String shaHex(final String data) {
  793.         return sha1Hex(data);
  794.     }

  795.     /**
  796.      * Updates the given {@link MessageDigest}.
  797.      *
  798.      * @param messageDigest
  799.      *            the {@link MessageDigest} to update
  800.      * @param valueToDigest
  801.      *            the value to update the {@link MessageDigest} with
  802.      * @return the updated {@link MessageDigest}
  803.      * @since 1.7
  804.      */
  805.     public static MessageDigest updateDigest(final MessageDigest messageDigest, final byte[] valueToDigest) {
  806.         messageDigest.update(valueToDigest);
  807.         return messageDigest;
  808.     }

  809.     /**
  810.      * Updates the given {@link MessageDigest}.
  811.      *
  812.      * @param messageDigest
  813.      *            the {@link MessageDigest} to update
  814.      * @param valueToDigest
  815.      *            the value to update the {@link MessageDigest} with
  816.      * @return the updated {@link MessageDigest}
  817.      * @since 1.11
  818.      */
  819.     public static MessageDigest updateDigest(final MessageDigest messageDigest, final ByteBuffer valueToDigest) {
  820.         messageDigest.update(valueToDigest);
  821.         return messageDigest;
  822.     }

  823.     /**
  824.      * Reads through a File and updates the digest for the data
  825.      *
  826.      * @param digest
  827.      *            The MessageDigest to use (e.g. MD5)
  828.      * @param data
  829.      *            Data to digest
  830.      * @return the digest
  831.      * @throws IOException
  832.      *             On error reading from the stream
  833.      * @since 1.11
  834.      */
  835.     public static MessageDigest updateDigest(final MessageDigest digest, final File data) throws IOException {
  836.         final BufferedInputStream stream = new BufferedInputStream(new FileInputStream(data));
  837.         try {
  838.             return updateDigest(digest, stream);
  839.         } finally {
  840.             stream.close();
  841.         }
  842.     }

  843.     /**
  844.      * Reads through an InputStream and updates the digest for the data
  845.      *
  846.      * @param digest
  847.      *            The MessageDigest to use (e.g. MD5)
  848.      * @param data
  849.      *            Data to digest
  850.      * @return the digest
  851.      * @throws IOException
  852.      *             On error reading from the stream
  853.      * @since 1.8
  854.      */
  855.     public static MessageDigest updateDigest(final MessageDigest digest, final InputStream data) throws IOException {
  856.         final byte[] buffer = new byte[STREAM_BUFFER_LENGTH];
  857.         int read = data.read(buffer, 0, STREAM_BUFFER_LENGTH);

  858.         while (read > -1) {
  859.             digest.update(buffer, 0, read);
  860.             read = data.read(buffer, 0, STREAM_BUFFER_LENGTH);
  861.         }

  862.         return digest;
  863.     }

  864.     /**
  865.      * Updates the given {@link MessageDigest} from a String (converted to bytes using UTF-8).
  866.      * <p>
  867.      * To update the digest using a different charset for the conversion,
  868.      * convert the String to a byte array using
  869.      * {@link String#getBytes(java.nio.charset.Charset)} and pass that
  870.      * to the {@link DigestUtils#updateDigest(MessageDigest, byte[])} method
  871.      *
  872.      * @param messageDigest
  873.      *            the {@link MessageDigest} to update
  874.      * @param valueToDigest
  875.      *            the value to update the {@link MessageDigest} with;
  876.      *            converted to bytes using {@link StringUtils#getBytesUtf8(String)}
  877.      * @return the updated {@link MessageDigest}
  878.      * @since 1.7
  879.      */
  880.     public static MessageDigest updateDigest(final MessageDigest messageDigest, final String valueToDigest) {
  881.         messageDigest.update(StringUtils.getBytesUtf8(valueToDigest));
  882.         return messageDigest;
  883.     }

  884.     /**
  885.      * Test whether the algorithm is supported.
  886.      * @param messageDigestAlgorithm the algorithm name
  887.      * @return {@code true} if the algorithm can be found
  888.      * @since 1.11
  889.      */
  890.     public static boolean isAvailable(final String messageDigestAlgorithm) {
  891.         return getDigest(messageDigestAlgorithm, null) != null;
  892.     }

  893.     private final MessageDigest messageDigest;

  894.    /**
  895.     * Preserves binary compatibity only.
  896.     * As for previous versions does not provide useful behaviour
  897.     * @deprecated since 1.11; only useful to preserve binary compatibility
  898.     */
  899.    @Deprecated
  900.     public DigestUtils() {
  901.         this.messageDigest = null;
  902.     }

  903.     /**
  904.      * Creates an instance using the provided {@link MessageDigest} parameter.
  905.      *
  906.      * This can then be used to create digests using methods such as
  907.      * {@link #digest(byte[])} and {@link #digestAsHex(File)}.
  908.      *
  909.      * @param digest the {@link MessageDigest} to use
  910.      * @since 1.11
  911.      */
  912.     public DigestUtils(final MessageDigest digest) {
  913.         this.messageDigest = digest;
  914.     }

  915.     /**
  916.      * Creates an instance using the provided {@link MessageDigest} parameter.
  917.      *
  918.      * This can then be used to create digests using methods such as
  919.      * {@link #digest(byte[])} and {@link #digestAsHex(File)}.
  920.      *
  921.      * @param name the name of the {@link MessageDigest} to use
  922.      * @see #getDigest(String)
  923.      * @throws IllegalArgumentException
  924.      *             when a {@link NoSuchAlgorithmException} is caught.
  925.      * @since 1.11
  926.      */
  927.     public DigestUtils(final String name) {
  928.         this(getDigest(name));
  929.     }

  930.     /**
  931.      * Returns the message digest instance.
  932.      * @return the message digest instance
  933.      * @since 1.11
  934.      */
  935.     public MessageDigest getMessageDigest() {
  936.         return messageDigest;
  937.     }

  938.     /**
  939.      * Reads through a byte array and returns the digest for the data.
  940.      *
  941.      * @param data
  942.      *            Data to digest
  943.      * @return the digest
  944.      * @since 1.11
  945.      */
  946.     public byte[] digest(final byte[] data) {
  947.         return updateDigest(messageDigest, data).digest();
  948.     }

  949.     /**
  950.      * Reads through a byte array and returns the digest for the data.
  951.      *
  952.      * @param data
  953.      *            Data to digest treated as UTF-8 string
  954.      * @return the digest
  955.      * @since 1.11
  956.      */
  957.     public byte[] digest(final String data) {
  958.         return updateDigest(messageDigest, data).digest();
  959.     }

  960.     /**
  961.      * Reads through a ByteBuffer and returns the digest for the data
  962.      *
  963.      * @param data
  964.      *            Data to digest
  965.      * @return the digest
  966.      *
  967.      * @since 1.11
  968.      */
  969.     public byte[] digest(final ByteBuffer data) {
  970.         return updateDigest(messageDigest, data).digest();
  971.     }

  972.     /**
  973.      * Reads through a File and returns the digest for the data
  974.      *
  975.      * @param data
  976.      *            Data to digest
  977.      * @return the digest
  978.      * @throws IOException
  979.      *             On error reading from the stream
  980.      * @since 1.11
  981.      */
  982.     public byte[] digest(final File data) throws IOException {
  983.         return updateDigest(messageDigest, data).digest();
  984.     }

  985.     /**
  986.      * Reads through an InputStream and returns the digest for the data
  987.      *
  988.      * @param data
  989.      *            Data to digest
  990.      * @return the digest
  991.      * @throws IOException
  992.      *             On error reading from the stream
  993.      * @since 1.11
  994.      */
  995.     public byte[] digest(final InputStream data) throws IOException {
  996.         return updateDigest(messageDigest, data).digest();
  997.     }

  998.     /**
  999.      * Reads through a byte array and returns the digest for the data.
  1000.      *
  1001.      * @param data
  1002.      *            Data to digest
  1003.      * @return the digest as a hex string
  1004.      * @since 1.11
  1005.      */
  1006.     public String digestAsHex(final byte[] data) {
  1007.         return Hex.encodeHexString(digest(data));
  1008.     }

  1009.     /**
  1010.      * Reads through a byte array and returns the digest for the data.
  1011.      *
  1012.      * @param data
  1013.      *            Data to digest treated as UTF-8 string
  1014.      * @return the digest as a hex string
  1015.      * @since 1.11
  1016.      */
  1017.     public String digestAsHex(final String data) {
  1018.         return Hex.encodeHexString(digest(data));
  1019.     }

  1020.     /**
  1021.      * Reads through a ByteBuffer and returns the digest for the data
  1022.      *
  1023.      * @param data
  1024.      *            Data to digest
  1025.      * @return the digest as a hex string
  1026.      *
  1027.      * @since 1.11
  1028.      */
  1029.     public String digestAsHex(final ByteBuffer data) {
  1030.         return Hex.encodeHexString(digest(data));
  1031.     }

  1032.     /**
  1033.      * Reads through a File and returns the digest for the data
  1034.      *
  1035.      * @param data
  1036.      *            Data to digest
  1037.      * @return the digest as a hex string
  1038.      * @throws IOException
  1039.      *             On error reading from the stream
  1040.      * @since 1.11
  1041.      */
  1042.     public String digestAsHex(final File data) throws IOException {
  1043.         return Hex.encodeHexString(digest(data));
  1044.     }

  1045.     /**
  1046.      * Reads through an InputStream and returns the digest for the data
  1047.      *
  1048.      * @param data
  1049.      *            Data to digest
  1050.      * @return the digest as a hex string
  1051.      * @throws IOException
  1052.      *             On error reading from the stream
  1053.      * @since 1.11
  1054.      */
  1055.     public String digestAsHex(final InputStream data) throws IOException {
  1056.         return Hex.encodeHexString(digest(data));
  1057.     }

  1058. }