001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018package org.apache.commons.codec.digest;
019
020import java.io.BufferedInputStream;
021import java.io.File;
022import java.io.FileInputStream;
023import java.io.IOException;
024import java.io.InputStream;
025import java.nio.ByteBuffer;
026import java.security.MessageDigest;
027import java.security.NoSuchAlgorithmException;
028
029import org.apache.commons.codec.binary.Hex;
030import org.apache.commons.codec.binary.StringUtils;
031
032/**
033 * Operations to simplify common {@link java.security.MessageDigest} tasks.
034 * This class is immutable and thread-safe.
035 * However the MessageDigest instances it creates generally won't be.
036 * <p>
037 * The {@link MessageDigestAlgorithms} class provides constants for standard
038 * digest algorithms that can be used with the {@link #getDigest(String)} method
039 * and other methods that require the Digest algorithm name.
040 * <p>
041 * Note: the class has short-hand methods for all the algorithms present as standard in Java 6.
042 * This approach requires lots of methods for each algorithm, and quickly becomes unwieldy.
043 * The following code works with all algorithms:
044 * <pre>
045 * import static org.apache.commons.codec.digest.MessageDigestAlgorithms.SHA_224;
046 * ...
047 * byte [] digest = new DigestUtils(SHA_224).digest(dataToDigest);
048 * String hdigest = new DigestUtils(SHA_224).digestAsHex(new File("pom.xml"));
049 * </pre>
050 * @see MessageDigestAlgorithms
051 */
052public class DigestUtils {
053
054    private static final int STREAM_BUFFER_LENGTH = 1024;
055
056    /**
057     * Reads through a byte array and returns the digest for the data. Provided for symmetry with other methods.
058     *
059     * @param messageDigest
060     *            The MessageDigest to use (e.g. MD5)
061     * @param data
062     *            Data to digest
063     * @return the digest
064     * @since 1.11
065     */
066    public static byte[] digest(final MessageDigest messageDigest, final byte[] data) {
067        return messageDigest.digest(data);
068    }
069
070    /**
071     * Reads through a ByteBuffer and returns the digest for the data
072     *
073     * @param messageDigest
074     *            The MessageDigest to use (e.g. MD5)
075     * @param data
076     *            Data to digest
077     * @return the digest
078     *
079     * @since 1.11
080     */
081    public static byte[] digest(final MessageDigest messageDigest, final ByteBuffer data) {
082        messageDigest.update(data);
083        return messageDigest.digest();
084    }
085
086    /**
087     * Reads through a File and returns the digest for the data
088     *
089     * @param messageDigest
090     *            The MessageDigest to use (e.g. MD5)
091     * @param data
092     *            Data to digest
093     * @return the digest
094     * @throws IOException
095     *             On error reading from the stream
096     * @since 1.11
097     */
098    public static byte[] digest(final MessageDigest messageDigest, final File data) throws IOException {
099        return updateDigest(messageDigest, data).digest();
100    }
101
102    /**
103     * Reads through an InputStream and returns the digest for the data
104     *
105     * @param messageDigest
106     *            The MessageDigest to use (e.g. MD5)
107     * @param data
108     *            Data to digest
109     * @return the digest
110     * @throws IOException
111     *             On error reading from the stream
112     * @since 1.11 (was private)
113     */
114    public static byte[] digest(final MessageDigest messageDigest, final InputStream data) throws IOException {
115        return updateDigest(messageDigest, data).digest();
116    }
117
118    /**
119     * Returns a <code>MessageDigest</code> for the given <code>algorithm</code>.
120     *
121     * @param algorithm
122     *            the name of the algorithm requested. See <a
123     *            href="http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA"
124     *            >Appendix A in the Java Cryptography Architecture Reference Guide</a> for information about standard
125     *            algorithm names.
126     * @return A digest instance.
127     * @see MessageDigest#getInstance(String)
128     * @throws IllegalArgumentException
129     *             when a {@link NoSuchAlgorithmException} is caught.
130     */
131    public static MessageDigest getDigest(final String algorithm) {
132        try {
133            return MessageDigest.getInstance(algorithm);
134        } catch (final NoSuchAlgorithmException e) {
135            throw new IllegalArgumentException(e);
136        }
137    }
138
139    /**
140     * Returns a <code>MessageDigest</code> for the given <code>algorithm</code> or a default if there is a problem
141     * getting the algorithm.
142     *
143     * @param algorithm
144     *            the name of the algorithm requested. See
145     *            <a href="http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA" >
146     *            Appendix A in the Java Cryptography Architecture Reference Guide</a> for information about standard
147     *            algorithm names.
148     * @param defaultMessageDigest
149     *            The default MessageDigest.
150     * @return A digest instance.
151     * @see MessageDigest#getInstance(String)
152     * @throws IllegalArgumentException
153     *             when a {@link NoSuchAlgorithmException} is caught.
154     * @since 1.11
155     */
156    public static MessageDigest getDigest(final String algorithm, final MessageDigest defaultMessageDigest) {
157        try {
158            return MessageDigest.getInstance(algorithm);
159        } catch (final Exception e) {
160            return defaultMessageDigest;
161        }
162    }
163
164    /**
165     * Returns an MD2 MessageDigest.
166     *
167     * @return An MD2 digest instance.
168     * @throws IllegalArgumentException
169     *             when a {@link NoSuchAlgorithmException} is caught, which should never happen because MD2 is a
170     *             built-in algorithm
171     * @see MessageDigestAlgorithms#MD2
172     * @since 1.7
173     */
174    public static MessageDigest getMd2Digest() {
175        return getDigest(MessageDigestAlgorithms.MD2);
176    }
177
178    /**
179     * Returns an MD5 MessageDigest.
180     *
181     * @return An MD5 digest instance.
182     * @throws IllegalArgumentException
183     *             when a {@link NoSuchAlgorithmException} is caught, which should never happen because MD5 is a
184     *             built-in algorithm
185     * @see MessageDigestAlgorithms#MD5
186     */
187    public static MessageDigest getMd5Digest() {
188        return getDigest(MessageDigestAlgorithms.MD5);
189    }
190
191    /**
192     * Returns an SHA-1 digest.
193     *
194     * @return An SHA-1 digest instance.
195     * @throws IllegalArgumentException
196     *             when a {@link NoSuchAlgorithmException} is caught, which should never happen because SHA-1 is a
197     *             built-in algorithm
198     * @see MessageDigestAlgorithms#SHA_1
199     * @since 1.7
200     */
201    public static MessageDigest getSha1Digest() {
202        return getDigest(MessageDigestAlgorithms.SHA_1);
203    }
204
205    /**
206     * Returns an SHA-256 digest.
207     *
208     * @return An SHA-256 digest instance.
209     * @throws IllegalArgumentException
210     *             when a {@link NoSuchAlgorithmException} is caught, which should never happen because SHA-256 is a
211     *             built-in algorithm
212     * @see MessageDigestAlgorithms#SHA_256
213     */
214    public static MessageDigest getSha256Digest() {
215        return getDigest(MessageDigestAlgorithms.SHA_256);
216    }
217
218    /**
219     * Returns an SHA3-224 digest.
220     *
221     * @return An SHA3-224 digest instance.
222     * @throws IllegalArgumentException
223     *             when a {@link NoSuchAlgorithmException} is caught, which should not happen on
224     *             Oracle Java 9 andgreater.
225     * @see MessageDigestAlgorithms#SHA3_224
226     * @since 1.12
227     */
228    public static MessageDigest getSha3_224Digest() {
229        return getDigest(MessageDigestAlgorithms.SHA3_224);
230    }
231
232    /**
233     * Returns an SHA3-256 digest.
234     *
235     * @return An SHA3-256 digest instance.
236     * @throws IllegalArgumentException
237     *             when a {@link NoSuchAlgorithmException} is caught, which should not happen on
238     *             Oracle Java 9 and greater.
239     * @see MessageDigestAlgorithms#SHA3_256
240     * @since 1.12
241     */
242    public static MessageDigest getSha3_256Digest() {
243        return getDigest(MessageDigestAlgorithms.SHA3_256);
244    }
245
246    /**
247     * Returns an SHA3-384 digest.
248     *
249     * @return An SHA3-384 digest instance.
250     * @throws IllegalArgumentException
251     *             when a {@link NoSuchAlgorithmException} is caught, which should not happen on
252     *             Oracle Java 9 and greater.
253     * @see MessageDigestAlgorithms#SHA3_384
254     * @since 1.12
255     */
256    public static MessageDigest getSha3_384Digest() {
257        return getDigest(MessageDigestAlgorithms.SHA3_384);
258    }
259
260    /**
261     * Returns an SHA3-512 digest.
262     *
263     * @return An SHA3-512 digest instance.
264     * @throws IllegalArgumentException
265     *             when a {@link NoSuchAlgorithmException} is caught, which should not happen
266     *             on Oracle Java 9 and greater.
267     * @see MessageDigestAlgorithms#SHA3_512
268     * @since 1.12
269     */
270    public static MessageDigest getSha3_512Digest() {
271        return getDigest(MessageDigestAlgorithms.SHA3_512);
272    }
273
274    /**
275     * Returns an SHA-384 digest.
276     *
277     * @return An SHA-384 digest instance.
278     * @throws IllegalArgumentException
279     *             when a {@link NoSuchAlgorithmException} is caught, which should never happen
280     *             because SHA-384 is a built-in algorithm
281     * @see MessageDigestAlgorithms#SHA_384
282     */
283    public static MessageDigest getSha384Digest() {
284        return getDigest(MessageDigestAlgorithms.SHA_384);
285    }
286
287    /**
288     * Returns an SHA-512 digest.
289     *
290     * @return An SHA-512 digest instance.
291     * @throws IllegalArgumentException
292     *             when a {@link NoSuchAlgorithmException} is caught, which should never happen
293     *             because SHA-512 is a built-in algorithm
294     * @see MessageDigestAlgorithms#SHA_512
295     */
296    public static MessageDigest getSha512Digest() {
297        return getDigest(MessageDigestAlgorithms.SHA_512);
298    }
299
300    /**
301     * Returns an SHA-1 digest.
302     *
303     * @return An SHA-1 digest instance.
304     * @throws IllegalArgumentException
305     *             when a {@link NoSuchAlgorithmException} is caught
306     * @deprecated (1.11) Use {@link #getSha1Digest()}
307     */
308    @Deprecated
309    public static MessageDigest getShaDigest() {
310        return getSha1Digest();
311    }
312
313    /**
314     * Test whether the algorithm is supported.
315     * @param messageDigestAlgorithm the algorithm name
316     * @return {@code true} if the algorithm can be found
317     * @since 1.11
318     */
319    public static boolean isAvailable(final String messageDigestAlgorithm) {
320        return getDigest(messageDigestAlgorithm, null) != null;
321    }
322
323    /**
324     * Calculates the MD2 digest and returns the value as a 16 element <code>byte[]</code>.
325     *
326     * @param data
327     *            Data to digest
328     * @return MD2 digest
329     * @since 1.7
330     */
331    public static byte[] md2(final byte[] data) {
332        return getMd2Digest().digest(data);
333    }
334
335    /**
336     * Calculates the MD2 digest and returns the value as a 16 element <code>byte[]</code>.
337     *
338     * @param data
339     *            Data to digest
340     * @return MD2 digest
341     * @throws IOException
342     *             On error reading from the stream
343     * @since 1.7
344     */
345    public static byte[] md2(final InputStream data) throws IOException {
346        return digest(getMd2Digest(), data);
347    }
348
349    /**
350     * Calculates the MD2 digest and returns the value as a 16 element <code>byte[]</code>.
351     *
352     * @param data
353     *            Data to digest; converted to bytes using {@link StringUtils#getBytesUtf8(String)}
354     * @return MD2 digest
355     * @since 1.7
356     */
357    public static byte[] md2(final String data) {
358        return md2(StringUtils.getBytesUtf8(data));
359    }
360
361    /**
362     * Calculates the MD2 digest and returns the value as a 32 character hex string.
363     *
364     * @param data
365     *            Data to digest
366     * @return MD2 digest as a hex string
367     * @since 1.7
368     */
369    public static String md2Hex(final byte[] data) {
370        return Hex.encodeHexString(md2(data));
371    }
372
373    /**
374     * Calculates the MD2 digest and returns the value as a 32 character hex string.
375     *
376     * @param data
377     *            Data to digest
378     * @return MD2 digest as a hex string
379     * @throws IOException
380     *             On error reading from the stream
381     * @since 1.7
382     */
383    public static String md2Hex(final InputStream data) throws IOException {
384        return Hex.encodeHexString(md2(data));
385    }
386
387    /**
388     * Calculates the MD2 digest and returns the value as a 32 character hex string.
389     *
390     * @param data
391     *            Data to digest
392     * @return MD2 digest as a hex string
393     * @since 1.7
394     */
395    public static String md2Hex(final String data) {
396        return Hex.encodeHexString(md2(data));
397    }
398
399    /**
400     * Calculates the MD5 digest and returns the value as a 16 element <code>byte[]</code>.
401     *
402     * @param data
403     *            Data to digest
404     * @return MD5 digest
405     */
406    public static byte[] md5(final byte[] data) {
407        return getMd5Digest().digest(data);
408    }
409
410    /**
411     * Calculates the MD5 digest and returns the value as a 16 element <code>byte[]</code>.
412     *
413     * @param data
414     *            Data to digest
415     * @return MD5 digest
416     * @throws IOException
417     *             On error reading from the stream
418     * @since 1.4
419     */
420    public static byte[] md5(final InputStream data) throws IOException {
421        return digest(getMd5Digest(), data);
422    }
423
424    /**
425     * Calculates the MD5 digest and returns the value as a 16 element <code>byte[]</code>.
426     *
427     * @param data
428     *            Data to digest; converted to bytes using {@link StringUtils#getBytesUtf8(String)}
429     * @return MD5 digest
430     */
431    public static byte[] md5(final String data) {
432        return md5(StringUtils.getBytesUtf8(data));
433    }
434
435    /**
436     * Calculates the MD5 digest and returns the value as a 32 character hex string.
437     *
438     * @param data
439     *            Data to digest
440     * @return MD5 digest as a hex string
441     */
442    public static String md5Hex(final byte[] data) {
443        return Hex.encodeHexString(md5(data));
444    }
445
446    /**
447     * Calculates the MD5 digest and returns the value as a 32 character hex string.
448     *
449     * @param data
450     *            Data to digest
451     * @return MD5 digest as a hex string
452     * @throws IOException
453     *             On error reading from the stream
454     * @since 1.4
455     */
456    public static String md5Hex(final InputStream data) throws IOException {
457        return Hex.encodeHexString(md5(data));
458    }
459
460    /**
461     * Calculates the MD5 digest and returns the value as a 32 character hex string.
462     *
463     * @param data
464     *            Data to digest
465     * @return MD5 digest as a hex string
466     */
467    public static String md5Hex(final String data) {
468        return Hex.encodeHexString(md5(data));
469    }
470
471    /**
472     * Calculates the SHA-1 digest and returns the value as a <code>byte[]</code>.
473     *
474     * @param data
475     *            Data to digest
476     * @return SHA-1 digest
477     * @deprecated (1.11) Use {@link #sha1(byte[])}
478     */
479    @Deprecated
480    public static byte[] sha(final byte[] data) {
481        return sha1(data);
482    }
483
484    /**
485     * Calculates the SHA-1 digest and returns the value as a <code>byte[]</code>.
486     *
487     * @param data
488     *            Data to digest
489     * @return SHA-1 digest
490     * @throws IOException
491     *             On error reading from the stream
492     * @since 1.4
493     * @deprecated (1.11) Use {@link #sha1(InputStream)}
494     */
495    @Deprecated
496    public static byte[] sha(final InputStream data) throws IOException {
497        return sha1(data);
498    }
499
500    /**
501     * Calculates the SHA-1 digest and returns the value as a <code>byte[]</code>.
502     *
503     * @param data
504     *            Data to digest
505     * @return SHA-1 digest
506     * @deprecated (1.11) Use {@link #sha1(String)}
507     */
508    @Deprecated
509    public static byte[] sha(final String data) {
510        return sha1(data);
511    }
512
513    /**
514     * Calculates the SHA-1 digest and returns the value as a <code>byte[]</code>.
515     *
516     * @param data
517     *            Data to digest
518     * @return SHA-1 digest
519     * @since 1.7
520     */
521    public static byte[] sha1(final byte[] data) {
522        return getSha1Digest().digest(data);
523    }
524
525    /**
526     * Calculates the SHA-1 digest and returns the value as a <code>byte[]</code>.
527     *
528     * @param data
529     *            Data to digest
530     * @return SHA-1 digest
531     * @throws IOException
532     *             On error reading from the stream
533     * @since 1.7
534     */
535    public static byte[] sha1(final InputStream data) throws IOException {
536        return digest(getSha1Digest(), data);
537    }
538
539    /**
540     * Calculates the SHA-1 digest and returns the value as a <code>byte[]</code>.
541     *
542     * @param data
543     *            Data to digest; converted to bytes using {@link StringUtils#getBytesUtf8(String)}
544     * @return SHA-1 digest
545     */
546    public static byte[] sha1(final String data) {
547        return sha1(StringUtils.getBytesUtf8(data));
548    }
549
550    /**
551     * Calculates the SHA-1 digest and returns the value as a hex string.
552     *
553     * @param data
554     *            Data to digest
555     * @return SHA-1 digest as a hex string
556     * @since 1.7
557     */
558    public static String sha1Hex(final byte[] data) {
559        return Hex.encodeHexString(sha1(data));
560    }
561
562    /**
563     * Calculates the SHA-1 digest and returns the value as a hex string.
564     *
565     * @param data
566     *            Data to digest
567     * @return SHA-1 digest as a hex string
568     * @throws IOException
569     *             On error reading from the stream
570     * @since 1.7
571     */
572    public static String sha1Hex(final InputStream data) throws IOException {
573        return Hex.encodeHexString(sha1(data));
574    }
575
576    /**
577     * Calculates the SHA-1 digest and returns the value as a hex string.
578     *
579     * @param data
580     *            Data to digest
581     * @return SHA-1 digest as a hex string
582     * @since 1.7
583     */
584    public static String sha1Hex(final String data) {
585        return Hex.encodeHexString(sha1(data));
586    }
587
588    /**
589     * Calculates the SHA-256 digest and returns the value as a <code>byte[]</code>.
590     *
591     * @param data
592     *            Data to digest
593     * @return SHA-256 digest
594     * @since 1.4
595     */
596    public static byte[] sha256(final byte[] data) {
597        return getSha256Digest().digest(data);
598    }
599
600    /**
601     * Calculates the SHA-256 digest and returns the value as a <code>byte[]</code>.
602     *
603     * @param data
604     *            Data to digest
605     * @return SHA-256 digest
606     * @throws IOException
607     *             On error reading from the stream
608     * @since 1.4
609     */
610    public static byte[] sha256(final InputStream data) throws IOException {
611        return digest(getSha256Digest(), data);
612    }
613
614    /**
615     * Calculates the SHA-256 digest and returns the value as a <code>byte[]</code>.
616     *
617     * @param data
618     *            Data to digest; converted to bytes using {@link StringUtils#getBytesUtf8(String)}
619     * @return SHA-256 digest
620     * @since 1.4
621     */
622    public static byte[] sha256(final String data) {
623        return sha256(StringUtils.getBytesUtf8(data));
624    }
625
626    /**
627     * Calculates the SHA-256 digest and returns the value as a hex string.
628     *
629     * @param data
630     *            Data to digest
631     * @return SHA-256 digest as a hex string
632     * @since 1.4
633     */
634    public static String sha256Hex(final byte[] data) {
635        return Hex.encodeHexString(sha256(data));
636    }
637
638    /**
639     * Calculates the SHA-256 digest and returns the value as a hex string.
640     *
641     * @param data
642     *            Data to digest
643     * @return SHA-256 digest as a hex string
644     * @throws IOException
645     *             On error reading from the stream
646     * @since 1.4
647     */
648    public static String sha256Hex(final InputStream data) throws IOException {
649        return Hex.encodeHexString(sha256(data));
650    }
651
652    /**
653     * Calculates the SHA-256 digest and returns the value as a hex string.
654     *
655     * @param data
656     *            Data to digest
657     * @return SHA-256 digest as a hex string
658     * @since 1.4
659     */
660    public static String sha256Hex(final String data) {
661        return Hex.encodeHexString(sha256(data));
662    }
663
664    /**
665     * Calculates the SHA3-224 digest and returns the value as a <code>byte[]</code>.
666     *
667     * @param data
668     *            Data to digest
669     * @return SHA3-224 digest
670     * @since 1.12
671     */
672    public static byte[] sha3_224(final byte[] data) {
673        return getSha3_224Digest().digest(data);
674    }
675
676    /**
677     * Calculates the SHA3-224 digest and returns the value as a <code>byte[]</code>.
678     *
679     * @param data
680     *            Data to digest
681     * @return SHA3-224 digest
682     * @throws IOException
683     *             On error reading from the stream
684     * @since 1.12
685     */
686    public static byte[] sha3_224(final InputStream data) throws IOException {
687        return digest(getSha3_224Digest(), data);
688    }
689
690    /**
691     * Calculates the SHA3-224 digest and returns the value as a <code>byte[]</code>.
692     *
693     * @param data
694     *            Data to digest; converted to bytes using {@link StringUtils#getBytesUtf8(String)}
695     * @return SHA3-224 digest
696     * @since 1.12
697     */
698    public static byte[] sha3_224(final String data) {
699        return sha3_224(StringUtils.getBytesUtf8(data));
700    }
701
702    /**
703     * Calculates the SHA3-224 digest and returns the value as a hex string.
704     *
705     * @param data
706     *            Data to digest
707     * @return SHA3-224 digest as a hex string
708     * @since 1.12
709     */
710    public static String sha3_224Hex(final String data) {
711        return Hex.encodeHexString(sha3_224(data));
712    }
713
714    /**
715     * Calculates the SHA3-256 digest and returns the value as a <code>byte[]</code>.
716     *
717     * @param data
718     *            Data to digest
719     * @return SHA3-256 digest
720     * @since 1.12
721     */
722    public static byte[] sha3_256(final byte[] data) {
723        return getSha3_256Digest().digest(data);
724    }
725
726    /**
727     * Calculates the SHA3-256 digest and returns the value as a <code>byte[]</code>.
728     *
729     * @param data
730     *            Data to digest
731     * @return SHA3-256 digest
732     * @throws IOException
733     *             On error reading from the stream
734     * @since 1.12
735     */
736    public static byte[] sha3_256(final InputStream data) throws IOException {
737        return digest(getSha3_256Digest(), data);
738    }
739
740    /**
741     * Calculates the SHA3-256 digest and returns the value as a <code>byte[]</code>.
742     *
743     * @param data
744     *            Data to digest; converted to bytes using {@link StringUtils#getBytesUtf8(String)}
745     * @return SHA3-256 digest
746     * @since 1.12
747     */
748    public static byte[] sha3_256(final String data) {
749        return sha3_256(StringUtils.getBytesUtf8(data));
750    }
751
752    /**
753     * Calculates the SHA3-256 digest and returns the value as a hex string.
754     *
755     * @param data
756     *            Data to digest
757     * @return SHA3-256 digest as a hex string
758     * @since 1.12
759     */
760    public static String sha3_256Hex(final String data) {
761        return Hex.encodeHexString(sha3_256(data));
762    }
763
764    /**
765     * Calculates the SHA3-384 digest and returns the value as a <code>byte[]</code>.
766     *
767     * @param data
768     *            Data to digest
769     * @return SHA3-384 digest
770     * @since 1.12
771     */
772    public static byte[] sha3_384(final byte[] data) {
773        return getSha3_384Digest().digest(data);
774    }
775
776    /**
777     * Calculates the SHA3-384 digest and returns the value as a <code>byte[]</code>.
778     *
779     * @param data
780     *            Data to digest
781     * @return SHA3-384 digest
782     * @throws IOException
783     *             On error reading from the stream
784     * @since 1.12
785     */
786    public static byte[] sha3_384(final InputStream data) throws IOException {
787        return digest(getSha3_384Digest(), data);
788    }
789
790    /**
791     * Calculates the SHA3-384 digest and returns the value as a <code>byte[]</code>.
792     *
793     * @param data
794     *            Data to digest; converted to bytes using {@link StringUtils#getBytesUtf8(String)}
795     * @return SHA3-384 digest
796     * @since 1.12
797     */
798    public static byte[] sha3_384(final String data) {
799        return sha3_384(StringUtils.getBytesUtf8(data));
800    }
801
802    /**
803     * Calculates the SHA3-384 digest and returns the value as a hex string.
804     *
805     * @param data
806     *            Data to digest
807     * @return SHA3-384 digest as a hex string
808     * @since 1.12
809     */
810    public static String sha3_384Hex(final String data) {
811        return Hex.encodeHexString(sha3_384(data));
812    }
813
814    /**
815     * Calculates the SHA3-512 digest and returns the value as a <code>byte[]</code>.
816     *
817     * @param data
818     *            Data to digest
819     * @return SHA3-512 digest
820     * @since 1.12
821     */
822    public static byte[] sha3_512(final byte[] data) {
823        return getSha3_512Digest().digest(data);
824    }
825
826    /**
827     * Calculates the SHA3-512 digest and returns the value as a <code>byte[]</code>.
828     *
829     * @param data
830     *            Data to digest
831     * @return SHA3-512 digest
832     * @throws IOException
833     *             On error reading from the stream
834     * @since 1.12
835     */
836    public static byte[] sha3_512(final InputStream data) throws IOException {
837        return digest(getSha3_512Digest(), data);
838    }
839
840    /**
841     * Calculates the SHA3-512 digest and returns the value as a <code>byte[]</code>.
842     *
843     * @param data
844     *            Data to digest; converted to bytes using {@link StringUtils#getBytesUtf8(String)}
845     * @return SHA3-512 digest
846     * @since 1.12
847     */
848    public static byte[] sha3_512(final String data) {
849        return sha3_512(StringUtils.getBytesUtf8(data));
850    }
851
852    /**
853     * Calculates the SHA3-512 digest and returns the value as a hex string.
854     *
855     * @param data
856     *            Data to digest
857     * @return SHA3-512 digest as a hex string
858     * @since 1.12
859     */
860    public static String sha3_512Hex(final String data) {
861        return Hex.encodeHexString(sha3_512(data));
862    }
863
864    /**
865     * Calculates the SHA-384 digest and returns the value as a <code>byte[]</code>.
866     *
867     * @param data
868     *            Data to digest
869     * @return SHA-384 digest
870     * @since 1.4
871     */
872    public static byte[] sha384(final byte[] data) {
873        return getSha384Digest().digest(data);
874    }
875
876    /**
877     * Calculates the SHA-384 digest and returns the value as a <code>byte[]</code>.
878     *
879     * @param data
880     *            Data to digest
881     * @return SHA-384 digest
882     * @throws IOException
883     *             On error reading from the stream
884     * @since 1.4
885     */
886    public static byte[] sha384(final InputStream data) throws IOException {
887        return digest(getSha384Digest(), data);
888    }
889
890    /**
891     * Calculates the SHA-384 digest and returns the value as a <code>byte[]</code>.
892     *
893     * @param data
894     *            Data to digest; converted to bytes using {@link StringUtils#getBytesUtf8(String)}
895     * @return SHA-384 digest
896     * @since 1.4
897     */
898    public static byte[] sha384(final String data) {
899        return sha384(StringUtils.getBytesUtf8(data));
900    }
901
902    /**
903     * Calculates the SHA-384 digest and returns the value as a hex string.
904     *
905     * @param data
906     *            Data to digest
907     * @return SHA-384 digest as a hex string
908     * @since 1.4
909     */
910    public static String sha384Hex(final byte[] data) {
911        return Hex.encodeHexString(sha384(data));
912    }
913
914    /**
915     * Calculates the SHA-384 digest and returns the value as a hex string.
916     *
917     * @param data
918     *            Data to digest
919     * @return SHA-384 digest as a hex string
920     * @throws IOException
921     *             On error reading from the stream
922     * @since 1.4
923     */
924    public static String sha384Hex(final InputStream data) throws IOException {
925        return Hex.encodeHexString(sha384(data));
926    }
927
928    /**
929     * Calculates the SHA-384 digest and returns the value as a hex string.
930     *
931     * @param data
932     *            Data to digest
933     * @return SHA-384 digest as a hex string
934     * @since 1.4
935     */
936    public static String sha384Hex(final String data) {
937        return Hex.encodeHexString(sha384(data));
938    }
939
940    /**
941     * Calculates the SHA-512 digest and returns the value as a <code>byte[]</code>.
942     *
943     * @param data
944     *            Data to digest
945     * @return SHA-512 digest
946     * @since 1.4
947     */
948    public static byte[] sha512(final byte[] data) {
949        return getSha512Digest().digest(data);
950    }
951
952    /**
953     * Calculates the SHA-512 digest and returns the value as a <code>byte[]</code>.
954     *
955     * @param data
956     *            Data to digest
957     * @return SHA-512 digest
958     * @throws IOException
959     *             On error reading from the stream
960     * @since 1.4
961     */
962    public static byte[] sha512(final InputStream data) throws IOException {
963        return digest(getSha512Digest(), data);
964    }
965
966    /**
967     * Calculates the SHA-512 digest and returns the value as a <code>byte[]</code>.
968     *
969     * @param data
970     *            Data to digest; converted to bytes using {@link StringUtils#getBytesUtf8(String)}
971     * @return SHA-512 digest
972     * @since 1.4
973     */
974    public static byte[] sha512(final String data) {
975        return sha512(StringUtils.getBytesUtf8(data));
976    }
977
978    /**
979     * Calculates the SHA-512 digest and returns the value as a hex string.
980     *
981     * @param data
982     *            Data to digest
983     * @return SHA-512 digest as a hex string
984     * @since 1.4
985     */
986    public static String sha512Hex(final byte[] data) {
987        return Hex.encodeHexString(sha512(data));
988    }
989
990    /**
991     * Calculates the SHA3-224 digest and returns the value as a hex string.
992     *
993     * @param data
994     *            Data to digest
995     * @return SHA3-224 digest as a hex string
996     * @since 1.12
997     */
998    public static String sha3_224Hex(final byte[] data) {
999        return Hex.encodeHexString(sha3_224(data));
1000    }
1001
1002    /**
1003     * Calculates the SHA3-256 digest and returns the value as a hex string.
1004     *
1005     * @param data
1006     *            Data to digest
1007     * @return SHA3-256 digest as a hex string
1008     * @since 1.12
1009     */
1010    public static String sha3_256Hex(final byte[] data) {
1011        return Hex.encodeHexString(sha3_256(data));
1012    }
1013
1014    /**
1015     * Calculates the SHA3-384 digest and returns the value as a hex string.
1016     *
1017     * @param data
1018     *            Data to digest
1019     * @return SHA3-384 digest as a hex string
1020     * @since 1.12
1021     */
1022    public static String sha3_384Hex(final byte[] data) {
1023        return Hex.encodeHexString(sha3_384(data));
1024    }
1025
1026    /**
1027     * Calculates the SHA3-512 digest and returns the value as a hex string.
1028     *
1029     * @param data
1030     *            Data to digest
1031     * @return SHA3-512 digest as a hex string
1032     * @since 1.12
1033     */
1034    public static String sha3_512Hex(final byte[] data) {
1035        return Hex.encodeHexString(sha3_512(data));
1036    }
1037
1038    /**
1039     * Calculates the SHA-512 digest and returns the value as a hex string.
1040     *
1041     * @param data
1042     *            Data to digest
1043     * @return SHA-512 digest as a hex string
1044     * @throws IOException
1045     *             On error reading from the stream
1046     * @since 1.4
1047     */
1048    public static String sha512Hex(final InputStream data) throws IOException {
1049        return Hex.encodeHexString(sha512(data));
1050    }
1051
1052    /**
1053     * Calculates the SHA3-224 digest and returns the value as a hex string.
1054     *
1055     * @param data
1056     *            Data to digest
1057     * @return SHA3-224 digest as a hex string
1058     * @throws IOException
1059     *             On error reading from the stream
1060     * @since 1.12
1061     */
1062    public static String sha3_224Hex(final InputStream data) throws IOException {
1063        return Hex.encodeHexString(sha3_224(data));
1064    }
1065
1066    /**
1067     * Calculates the SHA3-256 digest and returns the value as a hex string.
1068     *
1069     * @param data
1070     *            Data to digest
1071     * @return SHA3-256 digest as a hex string
1072     * @throws IOException
1073     *             On error reading from the stream
1074     * @since 1.12
1075     */
1076    public static String sha3_256Hex(final InputStream data) throws IOException {
1077        return Hex.encodeHexString(sha3_256(data));
1078    }
1079
1080    /**
1081     * Calculates the SHA3-384 digest and returns the value as a hex string.
1082     *
1083     * @param data
1084     *            Data to digest
1085     * @return SHA3-384 digest as a hex string
1086     * @throws IOException
1087     *             On error reading from the stream
1088     * @since 1.12
1089     */
1090    public static String sha3_384Hex(final InputStream data) throws IOException {
1091        return Hex.encodeHexString(sha3_384(data));
1092    }
1093
1094    /**
1095     * Calculates the SHA3-512 digest and returns the value as a hex string.
1096     *
1097     * @param data
1098     *            Data to digest
1099     * @return SHA3-512 digest as a hex string
1100     * @throws IOException
1101     *             On error reading from the stream
1102     * @since 1.12
1103     */
1104    public static String sha3_512Hex(final InputStream data) throws IOException {
1105        return Hex.encodeHexString(sha3_512(data));
1106    }
1107
1108    /**
1109     * Calculates the SHA-512 digest and returns the value as a hex string.
1110     *
1111     * @param data
1112     *            Data to digest
1113     * @return SHA-512 digest as a hex string
1114     * @since 1.4
1115     */
1116    public static String sha512Hex(final String data) {
1117        return Hex.encodeHexString(sha512(data));
1118    }
1119
1120    /**
1121     * Calculates the SHA-1 digest and returns the value as a hex string.
1122     *
1123     * @param data
1124     *            Data to digest
1125     * @return SHA-1 digest as a hex string
1126     * @deprecated (1.11) Use {@link #sha1Hex(byte[])}
1127     */
1128    @Deprecated
1129    public static String shaHex(final byte[] data) {
1130        return sha1Hex(data);
1131    }
1132
1133    /**
1134     * Calculates the SHA-1 digest and returns the value as a hex string.
1135     *
1136     * @param data
1137     *            Data to digest
1138     * @return SHA-1 digest as a hex string
1139     * @throws IOException
1140     *             On error reading from the stream
1141     * @since 1.4
1142     * @deprecated (1.11) Use {@link #sha1Hex(InputStream)}
1143     */
1144    @Deprecated
1145    public static String shaHex(final InputStream data) throws IOException {
1146        return sha1Hex(data);
1147    }
1148
1149    /**
1150     * Calculates the SHA-1 digest and returns the value as a hex string.
1151     *
1152     * @param data
1153     *            Data to digest
1154     * @return SHA-1 digest as a hex string
1155     * @deprecated (1.11) Use {@link #sha1Hex(String)}
1156     */
1157    @Deprecated
1158    public static String shaHex(final String data) {
1159        return sha1Hex(data);
1160    }
1161
1162    /**
1163     * Updates the given {@link MessageDigest}.
1164     *
1165     * @param messageDigest
1166     *            the {@link MessageDigest} to update
1167     * @param valueToDigest
1168     *            the value to update the {@link MessageDigest} with
1169     * @return the updated {@link MessageDigest}
1170     * @since 1.7
1171     */
1172    public static MessageDigest updateDigest(final MessageDigest messageDigest, final byte[] valueToDigest) {
1173        messageDigest.update(valueToDigest);
1174        return messageDigest;
1175    }
1176
1177    /**
1178     * Updates the given {@link MessageDigest}.
1179     *
1180     * @param messageDigest
1181     *            the {@link MessageDigest} to update
1182     * @param valueToDigest
1183     *            the value to update the {@link MessageDigest} with
1184     * @return the updated {@link MessageDigest}
1185     * @since 1.11
1186     */
1187    public static MessageDigest updateDigest(final MessageDigest messageDigest, final ByteBuffer valueToDigest) {
1188        messageDigest.update(valueToDigest);
1189        return messageDigest;
1190    }
1191
1192    /**
1193     * Reads through a File and updates the digest for the data
1194     *
1195     * @param digest
1196     *            The MessageDigest to use (e.g. MD5)
1197     * @param data
1198     *            Data to digest
1199     * @return the digest
1200     * @throws IOException
1201     *             On error reading from the stream
1202     * @since 1.11
1203     */
1204    public static MessageDigest updateDigest(final MessageDigest digest, final File data) throws IOException {
1205        try (final BufferedInputStream stream = new BufferedInputStream(new FileInputStream(data))) {
1206            return updateDigest(digest, stream);
1207        }
1208    }
1209
1210    /**
1211     * Reads through an InputStream and updates the digest for the data
1212     *
1213     * @param digest
1214     *            The MessageDigest to use (e.g. MD5)
1215     * @param data
1216     *            Data to digest
1217     * @return the digest
1218     * @throws IOException
1219     *             On error reading from the stream
1220     * @since 1.8
1221     */
1222    public static MessageDigest updateDigest(final MessageDigest digest, final InputStream data) throws IOException {
1223        final byte[] buffer = new byte[STREAM_BUFFER_LENGTH];
1224        int read = data.read(buffer, 0, STREAM_BUFFER_LENGTH);
1225
1226        while (read > -1) {
1227            digest.update(buffer, 0, read);
1228            read = data.read(buffer, 0, STREAM_BUFFER_LENGTH);
1229        }
1230
1231        return digest;
1232    }
1233
1234    /**
1235     * Updates the given {@link MessageDigest} from a String (converted to bytes using UTF-8).
1236     * <p>
1237     * To update the digest using a different charset for the conversion,
1238     * convert the String to a byte array using
1239     * {@link String#getBytes(java.nio.charset.Charset)} and pass that
1240     * to the {@link DigestUtils#updateDigest(MessageDigest, byte[])} method
1241     *
1242     * @param messageDigest
1243     *            the {@link MessageDigest} to update
1244     * @param valueToDigest
1245     *            the value to update the {@link MessageDigest} with;
1246     *            converted to bytes using {@link StringUtils#getBytesUtf8(String)}
1247     * @return the updated {@link MessageDigest}
1248     * @since 1.7
1249     */
1250    public static MessageDigest updateDigest(final MessageDigest messageDigest, final String valueToDigest) {
1251        messageDigest.update(StringUtils.getBytesUtf8(valueToDigest));
1252        return messageDigest;
1253    }
1254
1255    private final MessageDigest messageDigest;
1256
1257   /**
1258    * Preserves binary compatibity only.
1259    * As for previous versions does not provide useful behaviour
1260    * @deprecated since 1.11; only useful to preserve binary compatibility
1261    */
1262   @Deprecated
1263    public DigestUtils() {
1264        this.messageDigest = null;
1265    }
1266
1267    /**
1268     * Creates an instance using the provided {@link MessageDigest} parameter.
1269     *
1270     * This can then be used to create digests using methods such as
1271     * {@link #digest(byte[])} and {@link #digestAsHex(File)}.
1272     *
1273     * @param digest the {@link MessageDigest} to use
1274     * @since 1.11
1275     */
1276    public DigestUtils(final MessageDigest digest) {
1277        this.messageDigest = digest;
1278    }
1279
1280    /**
1281     * Creates an instance using the provided {@link MessageDigest} parameter.
1282     *
1283     * This can then be used to create digests using methods such as
1284     * {@link #digest(byte[])} and {@link #digestAsHex(File)}.
1285     *
1286     * @param name the name of the {@link MessageDigest} to use
1287     * @see #getDigest(String)
1288     * @throws IllegalArgumentException
1289     *             when a {@link NoSuchAlgorithmException} is caught.
1290     * @since 1.11
1291     */
1292    public DigestUtils(final String name) {
1293        this(getDigest(name));
1294    }
1295
1296    /**
1297     * Reads through a byte array and returns the digest for the data.
1298     *
1299     * @param data
1300     *            Data to digest
1301     * @return the digest
1302     * @since 1.11
1303     */
1304    public byte[] digest(final byte[] data) {
1305        return updateDigest(messageDigest, data).digest();
1306    }
1307
1308    /**
1309     * Reads through a ByteBuffer and returns the digest for the data
1310     *
1311     * @param data
1312     *            Data to digest
1313     * @return the digest
1314     *
1315     * @since 1.11
1316     */
1317    public byte[] digest(final ByteBuffer data) {
1318        return updateDigest(messageDigest, data).digest();
1319    }
1320
1321    /**
1322     * Reads through a File and returns the digest for the data
1323     *
1324     * @param data
1325     *            Data to digest
1326     * @return the digest
1327     * @throws IOException
1328     *             On error reading from the stream
1329     * @since 1.11
1330     */
1331    public byte[] digest(final File data) throws IOException {
1332        return updateDigest(messageDigest, data).digest();
1333    }
1334
1335    /**
1336     * Reads through an InputStream and returns the digest for the data
1337     *
1338     * @param data
1339     *            Data to digest
1340     * @return the digest
1341     * @throws IOException
1342     *             On error reading from the stream
1343     * @since 1.11
1344     */
1345    public byte[] digest(final InputStream data) throws IOException {
1346        return updateDigest(messageDigest, data).digest();
1347    }
1348
1349    /**
1350     * Reads through a byte array and returns the digest for the data.
1351     *
1352     * @param data
1353     *            Data to digest treated as UTF-8 string
1354     * @return the digest
1355     * @since 1.11
1356     */
1357    public byte[] digest(final String data) {
1358        return updateDigest(messageDigest, data).digest();
1359    }
1360
1361    /**
1362     * Reads through a byte array and returns the digest for the data.
1363     *
1364     * @param data
1365     *            Data to digest
1366     * @return the digest as a hex string
1367     * @since 1.11
1368     */
1369    public String digestAsHex(final byte[] data) {
1370        return Hex.encodeHexString(digest(data));
1371    }
1372
1373    /**
1374     * Reads through a ByteBuffer and returns the digest for the data
1375     *
1376     * @param data
1377     *            Data to digest
1378     * @return the digest as a hex string
1379     *
1380     * @since 1.11
1381     */
1382    public String digestAsHex(final ByteBuffer data) {
1383        return Hex.encodeHexString(digest(data));
1384    }
1385
1386    /**
1387     * Reads through a File and returns the digest for the data
1388     *
1389     * @param data
1390     *            Data to digest
1391     * @return the digest as a hex string
1392     * @throws IOException
1393     *             On error reading from the stream
1394     * @since 1.11
1395     */
1396    public String digestAsHex(final File data) throws IOException {
1397        return Hex.encodeHexString(digest(data));
1398    }
1399
1400    /**
1401     * Reads through an InputStream and returns the digest for the data
1402     *
1403     * @param data
1404     *            Data to digest
1405     * @return the digest as a hex string
1406     * @throws IOException
1407     *             On error reading from the stream
1408     * @since 1.11
1409     */
1410    public String digestAsHex(final InputStream data) throws IOException {
1411        return Hex.encodeHexString(digest(data));
1412    }
1413
1414    /**
1415     * Reads through a byte array and returns the digest for the data.
1416     *
1417     * @param data
1418     *            Data to digest treated as UTF-8 string
1419     * @return the digest as a hex string
1420     * @since 1.11
1421     */
1422    public String digestAsHex(final String data) {
1423        return Hex.encodeHexString(digest(data));
1424    }
1425
1426    /**
1427     * Returns the message digest instance.
1428     * @return the message digest instance
1429     * @since 1.11
1430     */
1431    public MessageDigest getMessageDigest() {
1432        return messageDigest;
1433    }
1434
1435}