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    
018    package org.apache.commons.codec.digest;
019    
020    import java.io.IOException;
021    import java.io.InputStream;
022    import java.security.MessageDigest;
023    import java.security.NoSuchAlgorithmException;
024    
025    import org.apache.commons.codec.binary.Hex;
026    import 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.html 889935 2013-12-11 05:05:13Z ggregory $
033     */
034    public 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 MD5 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 An MD5 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
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
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
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
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
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
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 MD5 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         * @return the updated {@link MessageDigest}
812         * @since 1.7
813         */
814        public static MessageDigest updateDigest(final MessageDigest messageDigest, final String valueToDigest) {
815            messageDigest.update(StringUtils.getBytesUtf8(valueToDigest));
816            return messageDigest;
817        }
818    }