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 static org.apache.commons.codec.binary.StringUtils.getBytesUtf8;
021import static org.junit.Assert.assertEquals;
022import static org.junit.Assert.assertNotNull;
023
024import java.io.ByteArrayInputStream;
025import java.io.IOException;
026import java.security.MessageDigest;
027import java.util.Random;
028
029import org.apache.commons.codec.binary.Hex;
030import org.apache.commons.codec.binary.StringUtils;
031import org.junit.Test;
032
033/**
034 * Tests DigestUtils methods.
035 *
036 * @version $Id: DigestUtilsTest.html 891688 2013-12-24 20:49:46Z ggregory $
037 */
038public class DigestUtilsTest {
039
040    private final byte[] testData = new byte[1024*1024];
041
042    /* (non-Javadoc)
043     * @see junit.framework.TestCase#setUp()
044     */
045    protected void setUp() throws Exception {
046        new Random().nextBytes(testData);
047    }
048
049    @Test
050    public void testConstructable() {
051        assertNotNull(new DigestUtils());
052    }
053
054    @Test(expected=IllegalArgumentException.class)
055    public void testInternalNoSuchAlgorithmException() {
056        DigestUtils.getDigest("Bogus Bogus");
057    }
058
059    @Test
060    public void testMd2Hex() throws IOException {
061        // Examples from RFC 1319
062        assertEquals("8350e5a3e24c153df2275c9f80692773", DigestUtils.md2Hex(""));
063
064        assertEquals("32ec01ec4a6dac72c0ab96fb34c0b5d1", DigestUtils.md2Hex("a"));
065
066        assertEquals("da853b0d3f88d99b30283a69e6ded6bb", DigestUtils.md2Hex("abc"));
067
068        assertEquals("ab4f496bfb2a530b219ff33031fe06b0", DigestUtils.md2Hex("message digest"));
069
070        assertEquals("4e8ddff3650292ab5a4108c3aa47940b", DigestUtils.md2Hex("abcdefghijklmnopqrstuvwxyz"));
071
072        assertEquals(
073            "da33def2a42df13975352846c30338cd",
074            DigestUtils.md2Hex("ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789"));
075
076        assertEquals(
077            "d5976f79d83d3a0dc9806c3c66f3efd8",
078            DigestUtils.md2Hex("1234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890"));
079
080        assertEquals(DigestUtils.md2Hex(testData),
081                DigestUtils.md2Hex(new ByteArrayInputStream(testData)));
082    }
083
084    /**
085     * An MD2 hash converted to hex should always be 32 characters.
086     */
087    @Test
088    public void testMd2HexLength() {
089        String hashMe = "this is some string that is longer than 32 characters";
090        String hash = DigestUtils.md2Hex(getBytesUtf8(hashMe));
091        assertEquals(32, hash.length());
092
093        hashMe = "length < 32";
094        hash = DigestUtils.md2Hex(getBytesUtf8(hashMe));
095        assertEquals(32, hash.length());
096    }
097
098    /**
099     * An MD2 hash should always be a 16 element byte[].
100     */
101    @Test
102    public void testMd2Length() {
103        String hashMe = "this is some string that is longer than 16 characters";
104        byte[] hash = DigestUtils.md2(getBytesUtf8(hashMe));
105        assertEquals(16, hash.length);
106
107        hashMe = "length < 16";
108        hash = DigestUtils.md2(getBytesUtf8(hashMe));
109        assertEquals(16, hash.length);
110    }
111
112    @Test
113    public void testMd5Hex() throws IOException {
114        // Examples from RFC 1321
115        assertEquals("d41d8cd98f00b204e9800998ecf8427e", DigestUtils.md5Hex(""));
116
117        assertEquals("0cc175b9c0f1b6a831c399e269772661", DigestUtils.md5Hex("a"));
118
119        assertEquals("900150983cd24fb0d6963f7d28e17f72", DigestUtils.md5Hex("abc"));
120
121        assertEquals("f96b697d7cb7938d525a2f31aaf161d0", DigestUtils.md5Hex("message digest"));
122
123        assertEquals("c3fcd3d76192e4007dfb496cca67e13b", DigestUtils.md5Hex("abcdefghijklmnopqrstuvwxyz"));
124
125        assertEquals(
126            "d174ab98d277d9f5a5611c2c9f419d9f",
127            DigestUtils.md5Hex("ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789"));
128
129        assertEquals(
130            "57edf4a22be3c955ac49da2e2107b67a",
131            DigestUtils.md5Hex("1234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890"));
132
133        assertEquals(DigestUtils.md5Hex(testData),
134                DigestUtils.md5Hex(new ByteArrayInputStream(testData)));
135    }
136
137    /**
138     * An MD5 hash converted to hex should always be 32 characters.
139     */
140    @Test
141    public void testMd5HexLength() {
142        String hashMe = "this is some string that is longer than 32 characters";
143        String hash = DigestUtils.md5Hex(getBytesUtf8(hashMe));
144        assertEquals(32, hash.length());
145
146        hashMe = "length < 32";
147        hash = DigestUtils.md5Hex(getBytesUtf8(hashMe));
148        assertEquals(32, hash.length());
149    }
150
151    /**
152     * An MD5 hash should always be a 16 element byte[].
153     */
154    @Test
155    public void testMd5Length() {
156        String hashMe = "this is some string that is longer than 16 characters";
157        byte[] hash = DigestUtils.md5(getBytesUtf8(hashMe));
158        assertEquals(16, hash.length);
159
160        hashMe = "length < 16";
161        hash = DigestUtils.md5(getBytesUtf8(hashMe));
162        assertEquals(16, hash.length);
163    }
164
165    @Test
166    public void testSha1Hex() throws IOException {
167        // Examples from FIPS 180-1
168        assertEquals("a9993e364706816aba3e25717850c26c9cd0d89d", DigestUtils.sha1Hex("abc"));
169
170        assertEquals("a9993e364706816aba3e25717850c26c9cd0d89d", DigestUtils.sha1Hex(getBytesUtf8("abc")));
171
172        assertEquals(
173            "84983e441c3bd26ebaae4aa1f95129e5e54670f1",
174            DigestUtils.sha1Hex("abcdbcdecdefdefgefghfghighij" + "hijkijkljklmklmnlmnomnopnopq"));
175        assertEquals(DigestUtils.sha1Hex(testData),
176                DigestUtils.sha1Hex(new ByteArrayInputStream(testData)));
177    }
178
179    @Test
180    public void testSha1UpdateWithByteArray(){
181        final String d1 = "C'est un homme qui rentre dans un caf�, et plouf";
182        final String d2 = "C'est un homme, c'est qu'une t�te, on lui offre un cadeau: 'oh... encore un chapeau!'";
183
184        MessageDigest messageDigest = DigestUtils.getSha1Digest();
185        messageDigest.update(d1.getBytes());
186        messageDigest.update(d2.getBytes());
187        final String expectedResult = Hex.encodeHexString(messageDigest.digest());
188
189        messageDigest = DigestUtils.getSha1Digest();
190        DigestUtils.updateDigest(messageDigest, d1.getBytes());
191        DigestUtils.updateDigest(messageDigest, d2.getBytes());
192        final String actualResult = Hex.encodeHexString(messageDigest.digest());
193
194        assertEquals(expectedResult, actualResult);
195    }
196
197    @Test
198    public void testSha1UpdateWithString(){
199        final String d1 = "C'est un homme qui rentre dans un caf�, et plouf";
200        final String d2 = "C'est un homme, c'est qu'une t�te, on lui offre un cadeau: 'oh... encore un chapeau!'";
201
202        MessageDigest messageDigest = DigestUtils.getSha1Digest();
203        messageDigest.update(StringUtils.getBytesUtf8(d1));
204        messageDigest.update(StringUtils.getBytesUtf8(d2));
205        final String expectedResult = Hex.encodeHexString(messageDigest.digest());
206
207        messageDigest = DigestUtils.getSha1Digest();
208        DigestUtils.updateDigest(messageDigest, d1);
209        DigestUtils.updateDigest(messageDigest, d2);
210        final String actualResult = Hex.encodeHexString(messageDigest.digest());
211
212        assertEquals(expectedResult, actualResult);
213    }
214
215    @Test
216    public void testSha256() throws IOException {
217    // Examples from FIPS 180-2
218    assertEquals("ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad",
219             DigestUtils.sha256Hex("abc"));
220    assertEquals("ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad",
221             DigestUtils.sha256Hex(getBytesUtf8("abc")));
222    assertEquals("248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1",
223             DigestUtils.sha256Hex("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"));
224
225    assertEquals(DigestUtils.sha256Hex(testData),
226            DigestUtils.sha256Hex(new ByteArrayInputStream(testData)));
227    }
228
229    @Test
230    public void testSha384() throws IOException {
231    // Examples from FIPS 180-2
232    assertEquals("cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed" +
233             "8086072ba1e7cc2358baeca134c825a7",
234             DigestUtils.sha384Hex("abc"));
235    assertEquals("cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed" +
236             "8086072ba1e7cc2358baeca134c825a7",
237             DigestUtils.sha384Hex(getBytesUtf8("abc")));
238    assertEquals("09330c33f71147e83d192fc782cd1b4753111b173b3b05d22fa08086e3b0f712" +
239            "fcc7c71a557e2db966c3e9fa91746039",
240             DigestUtils.sha384Hex("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn" +
241                       "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"));
242    assertEquals(DigestUtils.sha384Hex(testData),
243            DigestUtils.sha384Hex(new ByteArrayInputStream(testData)));
244    }
245
246    @Test
247    public void testSha512() throws IOException {
248    // Examples from FIPS 180-2
249    assertEquals("ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a" +
250            "2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f",
251             DigestUtils.sha512Hex("abc"));
252    assertEquals("ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a" +
253             "2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f",
254             DigestUtils.sha512Hex(getBytesUtf8("abc")));
255    assertEquals("8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299aeadb6889018" +
256             "501d289e4900f7e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909",
257             DigestUtils.sha512Hex("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn" +
258                       "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"));
259    assertEquals(DigestUtils.sha512Hex(testData),
260            DigestUtils.sha512Hex(new ByteArrayInputStream(testData)));
261}
262
263    @SuppressWarnings("deprecation") // deliberate tests of deprecated code
264    @Test
265    public void testShaHex() throws IOException {
266        // Examples from FIPS 180-1
267        assertEquals("a9993e364706816aba3e25717850c26c9cd0d89d", DigestUtils.shaHex("abc"));
268
269        assertEquals("a9993e364706816aba3e25717850c26c9cd0d89d", DigestUtils.shaHex(getBytesUtf8("abc")));
270
271        assertEquals(
272            "84983e441c3bd26ebaae4aa1f95129e5e54670f1",
273            DigestUtils.shaHex("abcdbcdecdefdefgefghfghighij" + "hijkijkljklmklmnlmnomnopnopq"));
274        assertEquals(DigestUtils.shaHex(testData),
275                DigestUtils.shaHex(new ByteArrayInputStream(testData)));
276    }
277
278    @SuppressWarnings("deprecation") // deliberate tests of deprecated code
279    @Test
280    public void testShaUpdateWithByteArray(){
281        final String d1 = "C'est un homme qui rentre dans un caf�, et plouf";
282        final String d2 = "C'est un homme, c'est qu'une t�te, on lui offre un cadeau: 'oh... encore un chapeau!'";
283
284        MessageDigest messageDigest = DigestUtils.getShaDigest();
285        messageDigest.update(d1.getBytes());
286        messageDigest.update(d2.getBytes());
287        final String expectedResult = Hex.encodeHexString(messageDigest.digest());
288
289        messageDigest = DigestUtils.getShaDigest();
290        DigestUtils.updateDigest(messageDigest, d1.getBytes());
291        DigestUtils.updateDigest(messageDigest, d2.getBytes());
292        final String actualResult = Hex.encodeHexString(messageDigest.digest());
293
294        assertEquals(expectedResult, actualResult);
295    }
296
297    @SuppressWarnings("deprecation") // deliberate tests of deprecated code
298    @Test
299    public void testShaUpdateWithString(){
300        final String d1 = "C'est un homme qui rentre dans un caf�, et plouf";
301        final String d2 = "C'est un homme, c'est qu'une t�te, on lui offre un cadeau: 'oh... encore un chapeau!'";
302
303        MessageDigest messageDigest = DigestUtils.getShaDigest();
304        messageDigest.update(StringUtils.getBytesUtf8(d1));
305        messageDigest.update(StringUtils.getBytesUtf8(d2));
306        final String expectedResult = Hex.encodeHexString(messageDigest.digest());
307
308        messageDigest = DigestUtils.getShaDigest();
309        DigestUtils.updateDigest(messageDigest, d1);
310        DigestUtils.updateDigest(messageDigest, d2);
311        final String actualResult = Hex.encodeHexString(messageDigest.digest());
312
313        assertEquals(expectedResult, actualResult);
314    }
315
316}