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.IOException;
021import java.io.InputStream;
022import java.security.MessageDigest;
023import java.security.NoSuchAlgorithmException;
024
025import org.apache.commons.codec.binary.Hex;
026import org.apache.commons.codec.binary.StringUtils;
027
028/**
029 * Operations to simplify common {@link java.security.MessageDigest} tasks.
030 * This class is immutable and thread-safe.
031 *
032 * @version $Id: DigestUtils.java 1542813 2013-11-17 20:52:32Z tn $
033 */
034public class DigestUtils {
035
036    private static final int STREAM_BUFFER_LENGTH = 1024;
037
038    /**
039     * Read through an InputStream and returns the digest for the data
040     *
041     * @param digest
042     *            The MessageDigest to use (e.g. MD5)
043     * @param data
044     *            Data to digest
045     * @return the digest
046     * @throws IOException
047     *             On error reading from the stream
048     */
049    private static byte[] digest(final MessageDigest digest, final InputStream data) throws IOException {
050        return updateDigest(digest, data).digest();
051    }
052
053    /**
054     * Returns a <code>MessageDigest</code> for the given <code>algorithm</code>.
055     *
056     * @param algorithm
057     *            the name of the algorithm requested. See <a
058     *            href="http://java.sun.com/j2se/1.3/docs/guide/security/CryptoSpec.html#AppA">Appendix A in the Java
059     *            Cryptography Architecture API Specification & Reference</a> for information about standard algorithm
060     *            names.
061     * @return A digest instance.
062     * @see MessageDigest#getInstance(String)
063     * @throws IllegalArgumentException
064     *             when a {@link NoSuchAlgorithmException} is caught.
065     */
066    public static MessageDigest getDigest(final String algorithm) {
067        try {
068            return MessageDigest.getInstance(algorithm);
069        } catch (final NoSuchAlgorithmException e) {
070            throw new IllegalArgumentException(e);
071        }
072    }
073
074    /**
075     * Returns an MD2 MessageDigest.
076     *
077     * @return An MD2 digest instance.
078     * @throws IllegalArgumentException
079     *             when a {@link NoSuchAlgorithmException} is caught, which should never happen because MD2 is a
080     *             built-in algorithm
081     * @see MessageDigestAlgorithms#MD2
082     * @since 1.7
083     */
084    public static MessageDigest getMd2Digest() {
085        return getDigest(MessageDigestAlgorithms.MD2);
086    }
087
088    /**
089     * Returns an MD5 MessageDigest.
090     *
091     * @return An MD5 digest instance.
092     * @throws IllegalArgumentException
093     *             when a {@link NoSuchAlgorithmException} is caught, which should never happen because MD5 is a
094     *             built-in algorithm
095     * @see MessageDigestAlgorithms#MD5
096     */
097    public static MessageDigest getMd5Digest() {
098        return getDigest(MessageDigestAlgorithms.MD5);
099    }
100
101    /**
102     * Returns an SHA-1 digest.
103     *
104     * @return An SHA-1 digest instance.
105     * @throws IllegalArgumentException
106     *             when a {@link NoSuchAlgorithmException} is caught, which should never happen because SHA-1 is a
107     *             built-in algorithm
108     * @see MessageDigestAlgorithms#SHA_1
109     * @since 1.7
110     */
111    public static MessageDigest getSha1Digest() {
112        return getDigest(MessageDigestAlgorithms.SHA_1);
113    }
114
115    /**
116     * Returns an SHA-256 digest.
117     * <p>
118     * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
119     * </p>
120     *
121     * @return An SHA-256 digest instance.
122     * @throws IllegalArgumentException
123     *             when a {@link NoSuchAlgorithmException} is caught, which should never happen because SHA-256 is a
124     *             built-in algorithm
125     * @see MessageDigestAlgorithms#SHA_256
126     */
127    public static MessageDigest getSha256Digest() {
128        return getDigest(MessageDigestAlgorithms.SHA_256);
129    }
130
131    /**
132     * Returns an SHA-384 digest.
133     * <p>
134     * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
135     * </p>
136     *
137     * @return An SHA-384 digest instance.
138     * @throws IllegalArgumentException
139     *             when a {@link NoSuchAlgorithmException} is caught, which should never happen because SHA-384 is a
140     *             built-in algorithm
141     * @see MessageDigestAlgorithms#SHA_384
142     */
143    public static MessageDigest getSha384Digest() {
144        return getDigest(MessageDigestAlgorithms.SHA_384);
145    }
146
147    /**
148     * Returns an SHA-512 digest.
149     * <p>
150     * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
151     * </p>
152     *
153     * @return An SHA-512 digest instance.
154     * @throws IllegalArgumentException
155     *             when a {@link NoSuchAlgorithmException} is caught, which should never happen because SHA-512 is a
156     *             built-in algorithm
157     * @see MessageDigestAlgorithms#SHA_512
158     */
159    public static MessageDigest getSha512Digest() {
160        return getDigest(MessageDigestAlgorithms.SHA_512);
161    }
162
163    /**
164     * Returns an SHA-1 digest.
165     *
166     * @return An SHA-1 digest instance.
167     * @throws IllegalArgumentException
168     *             when a {@link NoSuchAlgorithmException} is caught
169     * @deprecated Use {@link #getSha1Digest()}
170     */
171    @Deprecated
172    public static MessageDigest getShaDigest() {
173        return getSha1Digest();
174    }
175
176    /**
177     * Calculates the MD2 digest and returns the value as a 16 element <code>byte[]</code>.
178     *
179     * @param data
180     *            Data to digest
181     * @return MD2 digest
182     * @since 1.7
183     */
184    public static byte[] md2(final byte[] data) {
185        return getMd2Digest().digest(data);
186    }
187
188    /**
189     * Calculates the MD2 digest and returns the value as a 16 element <code>byte[]</code>.
190     *
191     * @param data
192     *            Data to digest
193     * @return MD2 digest
194     * @throws IOException
195     *             On error reading from the stream
196     * @since 1.7
197     */
198    public static byte[] md2(final InputStream data) throws IOException {
199        return digest(getMd2Digest(), data);
200    }
201
202    /**
203     * Calculates the MD2 digest and returns the value as a 16 element <code>byte[]</code>.
204     *
205     * @param data
206     *            Data to digest; converted to bytes using {@link StringUtils#getBytesUtf8(String)}
207     * @return MD2 digest
208     * @since 1.7
209     */
210    public static byte[] md2(final String data) {
211        return md2(StringUtils.getBytesUtf8(data));
212    }
213
214    /**
215     * Calculates the MD2 digest and returns the value as a 32 character hex string.
216     *
217     * @param data
218     *            Data to digest
219     * @return MD2 digest as a hex string
220     * @since 1.7
221     */
222    public static String md2Hex(final byte[] data) {
223        return Hex.encodeHexString(md2(data));
224    }
225
226    /**
227     * Calculates the MD2 digest and returns the value as a 32 character hex string.
228     *
229     * @param data
230     *            Data to digest
231     * @return MD2 digest as a hex string
232     * @throws IOException
233     *             On error reading from the stream
234     * @since 1.7
235     */
236    public static String md2Hex(final InputStream data) throws IOException {
237        return Hex.encodeHexString(md2(data));
238    }
239
240    /**
241     * Calculates the MD2 digest and returns the value as a 32 character hex string.
242     *
243     * @param data
244     *            Data to digest
245     * @return MD2 digest as a hex string
246     * @since 1.7
247     */
248    public static String md2Hex(final String data) {
249        return Hex.encodeHexString(md2(data));
250    }
251
252    /**
253     * Calculates the MD5 digest and returns the value as a 16 element <code>byte[]</code>.
254     *
255     * @param data
256     *            Data to digest
257     * @return MD5 digest
258     */
259    public static byte[] md5(final byte[] data) {
260        return getMd5Digest().digest(data);
261    }
262
263    /**
264     * Calculates the MD5 digest and returns the value as a 16 element <code>byte[]</code>.
265     *
266     * @param data
267     *            Data to digest
268     * @return MD5 digest
269     * @throws IOException
270     *             On error reading from the stream
271     * @since 1.4
272     */
273    public static byte[] md5(final InputStream data) throws IOException {
274        return digest(getMd5Digest(), data);
275    }
276
277    /**
278     * Calculates the MD5 digest and returns the value as a 16 element <code>byte[]</code>.
279     *
280     * @param data
281     *            Data to digest; converted to bytes using {@link StringUtils#getBytesUtf8(String)}
282     * @return MD5 digest
283     */
284    public static byte[] md5(final String data) {
285        return md5(StringUtils.getBytesUtf8(data));
286    }
287
288    /**
289     * Calculates the MD5 digest and returns the value as a 32 character hex string.
290     *
291     * @param data
292     *            Data to digest
293     * @return MD5 digest as a hex string
294     */
295    public static String md5Hex(final byte[] data) {
296        return Hex.encodeHexString(md5(data));
297    }
298
299    /**
300     * Calculates the MD5 digest and returns the value as a 32 character hex string.
301     *
302     * @param data
303     *            Data to digest
304     * @return MD5 digest as a hex string
305     * @throws IOException
306     *             On error reading from the stream
307     * @since 1.4
308     */
309    public static String md5Hex(final InputStream data) throws IOException {
310        return Hex.encodeHexString(md5(data));
311    }
312
313    /**
314     * Calculates the MD5 digest and returns the value as a 32 character hex string.
315     *
316     * @param data
317     *            Data to digest
318     * @return MD5 digest as a hex string
319     */
320    public static String md5Hex(final String data) {
321        return Hex.encodeHexString(md5(data));
322    }
323
324    /**
325     * Calculates the SHA-1 digest and returns the value as a <code>byte[]</code>.
326     *
327     * @param data
328     *            Data to digest
329     * @return SHA-1 digest
330     * @deprecated Use {@link #sha1(byte[])}
331     */
332    @Deprecated
333    public static byte[] sha(final byte[] data) {
334        return sha1(data);
335    }
336
337    /**
338     * Calculates the SHA-1 digest and returns the value as a <code>byte[]</code>.
339     *
340     * @param data
341     *            Data to digest
342     * @return SHA-1 digest
343     * @throws IOException
344     *             On error reading from the stream
345     * @since 1.4
346     * @deprecated Use {@link #sha1(InputStream)}
347     */
348    @Deprecated
349    public static byte[] sha(final InputStream data) throws IOException {
350        return sha1(data);
351    }
352
353    /**
354     * Calculates the SHA-1 digest and returns the value as a <code>byte[]</code>.
355     *
356     * @param data
357     *            Data to digest
358     * @return SHA-1 digest
359     * @deprecated Use {@link #sha1(String)}
360     */
361    @Deprecated
362    public static byte[] sha(final String data) {
363        return sha1(data);
364    }
365
366    /**
367     * Calculates the SHA-1 digest and returns the value as a <code>byte[]</code>.
368     *
369     * @param data
370     *            Data to digest
371     * @return SHA-1 digest
372     * @since 1.7
373     */
374    public static byte[] sha1(final byte[] data) {
375        return getSha1Digest().digest(data);
376    }
377
378    /**
379     * Calculates the SHA-1 digest and returns the value as a <code>byte[]</code>.
380     *
381     * @param data
382     *            Data to digest
383     * @return SHA-1 digest
384     * @throws IOException
385     *             On error reading from the stream
386     * @since 1.7
387     */
388    public static byte[] sha1(final InputStream data) throws IOException {
389        return digest(getSha1Digest(), data);
390    }
391
392    /**
393     * Calculates the SHA-1 digest and returns the value as a <code>byte[]</code>.
394     *
395     * @param data
396     *            Data to digest; converted to bytes using {@link StringUtils#getBytesUtf8(String)}
397     * @return SHA-1 digest
398     */
399    public static byte[] sha1(final String data) {
400        return sha1(StringUtils.getBytesUtf8(data));
401    }
402
403    /**
404     * Calculates the SHA-1 digest and returns the value as a hex string.
405     *
406     * @param data
407     *            Data to digest
408     * @return SHA-1 digest as a hex string
409     * @since 1.7
410     */
411    public static String sha1Hex(final byte[] data) {
412        return Hex.encodeHexString(sha1(data));
413    }
414
415    /**
416     * Calculates the SHA-1 digest and returns the value as a hex string.
417     *
418     * @param data
419     *            Data to digest
420     * @return SHA-1 digest as a hex string
421     * @throws IOException
422     *             On error reading from the stream
423     * @since 1.7
424     */
425    public static String sha1Hex(final InputStream data) throws IOException {
426        return Hex.encodeHexString(sha1(data));
427    }
428
429    /**
430     * Calculates the SHA-1 digest and returns the value as a hex string.
431     *
432     * @param data
433     *            Data to digest
434     * @return SHA-1 digest as a hex string
435     * @since 1.7
436     */
437    public static String sha1Hex(final String data) {
438        return Hex.encodeHexString(sha1(data));
439    }
440
441    /**
442     * Calculates the SHA-256 digest and returns the value as a <code>byte[]</code>.
443     * <p>
444     * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
445     * </p>
446     *
447     * @param data
448     *            Data to digest
449     * @return SHA-256 digest
450     * @since 1.4
451     */
452    public static byte[] sha256(final byte[] data) {
453        return getSha256Digest().digest(data);
454    }
455
456    /**
457     * Calculates the SHA-256 digest and returns the value as a <code>byte[]</code>.
458     * <p>
459     * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
460     * </p>
461     *
462     * @param data
463     *            Data to digest
464     * @return SHA-256 digest
465     * @throws IOException
466     *             On error reading from the stream
467     * @since 1.4
468     */
469    public static byte[] sha256(final InputStream data) throws IOException {
470        return digest(getSha256Digest(), data);
471    }
472
473    /**
474     * Calculates the SHA-256 digest and returns the value as a <code>byte[]</code>.
475     * <p>
476     * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
477     * </p>
478     *
479     * @param data
480     *            Data to digest; converted to bytes using {@link StringUtils#getBytesUtf8(String)}
481     * @return SHA-256 digest
482     * @since 1.4
483     */
484    public static byte[] sha256(final String data) {
485        return sha256(StringUtils.getBytesUtf8(data));
486    }
487
488    /**
489     * Calculates the SHA-256 digest and returns the value as a hex string.
490     * <p>
491     * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
492     * </p>
493     *
494     * @param data
495     *            Data to digest
496     * @return SHA-256 digest as a hex string
497     * @since 1.4
498     */
499    public static String sha256Hex(final byte[] data) {
500        return Hex.encodeHexString(sha256(data));
501    }
502
503    /**
504     * Calculates the SHA-256 digest and returns the value as a hex string.
505     * <p>
506     * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
507     * </p>
508     *
509     * @param data
510     *            Data to digest
511     * @return SHA-256 digest as a hex string
512     * @throws IOException
513     *             On error reading from the stream
514     * @since 1.4
515     */
516    public static String sha256Hex(final InputStream data) throws IOException {
517        return Hex.encodeHexString(sha256(data));
518    }
519
520    /**
521     * Calculates the SHA-256 digest and returns the value as a hex string.
522     * <p>
523     * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
524     * </p>
525     *
526     * @param data
527     *            Data to digest
528     * @return SHA-256 digest as a hex string
529     * @since 1.4
530     */
531    public static String sha256Hex(final String data) {
532        return Hex.encodeHexString(sha256(data));
533    }
534
535    /**
536     * Calculates the SHA-384 digest and returns the value as a <code>byte[]</code>.
537     * <p>
538     * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
539     * </p>
540     *
541     * @param data
542     *            Data to digest
543     * @return SHA-384 digest
544     * @since 1.4
545     */
546    public static byte[] sha384(final byte[] data) {
547        return getSha384Digest().digest(data);
548    }
549
550    /**
551     * Calculates the SHA-384 digest and returns the value as a <code>byte[]</code>.
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-384 digest
559     * @throws IOException
560     *             On error reading from the stream
561     * @since 1.4
562     */
563    public static byte[] sha384(final InputStream data) throws IOException {
564        return digest(getSha384Digest(), data);
565    }
566
567    /**
568     * Calculates the SHA-384 digest and returns the value as a <code>byte[]</code>.
569     * <p>
570     * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
571     * </p>
572     *
573     * @param data
574     *            Data to digest; converted to bytes using {@link StringUtils#getBytesUtf8(String)}
575     * @return SHA-384 digest
576     * @since 1.4
577     */
578    public static byte[] sha384(final String data) {
579        return sha384(StringUtils.getBytesUtf8(data));
580    }
581
582    /**
583     * Calculates the SHA-384 digest and returns the value as a hex string.
584     * <p>
585     * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
586     * </p>
587     *
588     * @param data
589     *            Data to digest
590     * @return SHA-384 digest as a hex string
591     * @since 1.4
592     */
593    public static String sha384Hex(final byte[] data) {
594        return Hex.encodeHexString(sha384(data));
595    }
596
597    /**
598     * Calculates the SHA-384 digest and returns the value as a hex string.
599     * <p>
600     * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
601     * </p>
602     *
603     * @param data
604     *            Data to digest
605     * @return SHA-384 digest as a hex string
606     * @throws IOException
607     *             On error reading from the stream
608     * @since 1.4
609     */
610    public static String sha384Hex(final InputStream data) throws IOException {
611        return Hex.encodeHexString(sha384(data));
612    }
613
614    /**
615     * Calculates the SHA-384 digest and returns the value as a hex string.
616     * <p>
617     * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
618     * </p>
619     *
620     * @param data
621     *            Data to digest
622     * @return SHA-384 digest as a hex string
623     * @since 1.4
624     */
625    public static String sha384Hex(final String data) {
626        return Hex.encodeHexString(sha384(data));
627    }
628
629    /**
630     * Calculates the SHA-512 digest and returns the value as a <code>byte[]</code>.
631     * <p>
632     * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
633     * </p>
634     *
635     * @param data
636     *            Data to digest
637     * @return SHA-512 digest
638     * @since 1.4
639     */
640    public static byte[] sha512(final byte[] data) {
641        return getSha512Digest().digest(data);
642    }
643
644    /**
645     * Calculates the SHA-512 digest and returns the value as a <code>byte[]</code>.
646     * <p>
647     * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
648     * </p>
649     *
650     * @param data
651     *            Data to digest
652     * @return SHA-512 digest
653     * @throws IOException
654     *             On error reading from the stream
655     * @since 1.4
656     */
657    public static byte[] sha512(final InputStream data) throws IOException {
658        return digest(getSha512Digest(), data);
659    }
660
661    /**
662     * Calculates the SHA-512 digest and returns the value as a <code>byte[]</code>.
663     * <p>
664     * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
665     * </p>
666     *
667     * @param data
668     *            Data to digest; converted to bytes using {@link StringUtils#getBytesUtf8(String)}
669     * @return SHA-512 digest
670     * @since 1.4
671     */
672    public static byte[] sha512(final String data) {
673        return sha512(StringUtils.getBytesUtf8(data));
674    }
675
676    /**
677     * Calculates the SHA-512 digest and returns the value as a hex string.
678     * <p>
679     * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
680     * </p>
681     *
682     * @param data
683     *            Data to digest
684     * @return SHA-512 digest as a hex string
685     * @since 1.4
686     */
687    public static String sha512Hex(final byte[] data) {
688        return Hex.encodeHexString(sha512(data));
689    }
690
691    /**
692     * Calculates the SHA-512 digest and returns the value as a hex string.
693     * <p>
694     * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
695     * </p>
696     *
697     * @param data
698     *            Data to digest
699     * @return SHA-512 digest as a hex string
700     * @throws IOException
701     *             On error reading from the stream
702     * @since 1.4
703     */
704    public static String sha512Hex(final InputStream data) throws IOException {
705        return Hex.encodeHexString(sha512(data));
706    }
707
708    /**
709     * Calculates the SHA-512 digest and returns the value as a hex string.
710     * <p>
711     * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
712     * </p>
713     *
714     * @param data
715     *            Data to digest
716     * @return SHA-512 digest as a hex string
717     * @since 1.4
718     */
719    public static String sha512Hex(final String data) {
720        return Hex.encodeHexString(sha512(data));
721    }
722
723    /**
724     * Calculates the SHA-1 digest and returns the value as a hex string.
725     *
726     * @param data
727     *            Data to digest
728     * @return SHA-1 digest as a hex string
729     * @deprecated Use {@link #sha1Hex(byte[])}
730     */
731    @Deprecated
732    public static String shaHex(final byte[] data) {
733        return sha1Hex(data);
734    }
735
736    /**
737     * Calculates the SHA-1 digest and returns the value as a hex string.
738     *
739     * @param data
740     *            Data to digest
741     * @return SHA-1 digest as a hex string
742     * @throws IOException
743     *             On error reading from the stream
744     * @since 1.4
745     * @deprecated Use {@link #sha1Hex(InputStream)}
746     */
747    @Deprecated
748    public static String shaHex(final InputStream data) throws IOException {
749        return sha1Hex(data);
750    }
751
752    /**
753     * Calculates the SHA-1 digest and returns the value as a hex string.
754     *
755     * @param data
756     *            Data to digest
757     * @return SHA-1 digest as a hex string
758     * @deprecated Use {@link #sha1Hex(String)}
759     */
760    @Deprecated
761    public static String shaHex(final String data) {
762        return sha1Hex(data);
763    }
764
765    /**
766     * Updates the given {@link MessageDigest}.
767     *
768     * @param messageDigest
769     *            the {@link MessageDigest} to update
770     * @param valueToDigest
771     *            the value to update the {@link MessageDigest} with
772     * @return the updated {@link MessageDigest}
773     * @since 1.7
774     */
775    public static MessageDigest updateDigest(final MessageDigest messageDigest, final byte[] valueToDigest) {
776        messageDigest.update(valueToDigest);
777        return messageDigest;
778    }
779
780    /**
781     * Reads through an InputStream and updates the digest for the data
782     *
783     * @param digest
784     *            The MessageDigest to use (e.g. MD5)
785     * @param data
786     *            Data to digest
787     * @return the digest
788     * @throws IOException
789     *             On error reading from the stream
790     * @since 1.8
791     */
792    public static MessageDigest updateDigest(final MessageDigest digest, final InputStream data) throws IOException {
793        final byte[] buffer = new byte[STREAM_BUFFER_LENGTH];
794        int read = data.read(buffer, 0, STREAM_BUFFER_LENGTH);
795
796        while (read > -1) {
797            digest.update(buffer, 0, read);
798            read = data.read(buffer, 0, STREAM_BUFFER_LENGTH);
799        }
800
801        return digest;
802    }
803
804    /**
805     * Updates the given {@link MessageDigest}.
806     *
807     * @param messageDigest
808     *            the {@link MessageDigest} to update
809     * @param valueToDigest
810     *            the value to update the {@link MessageDigest} with;
811     *            converted to bytes using {@link StringUtils#getBytesUtf8(String)}
812     * @return the updated {@link MessageDigest}
813     * @since 1.7
814     */
815    public static MessageDigest updateDigest(final MessageDigest messageDigest, final String valueToDigest) {
816        messageDigest.update(StringUtils.getBytesUtf8(valueToDigest));
817        return messageDigest;
818    }
819}