Skip to content

Commit 0752e9a

Browse files
committed
Applying CODEC-52; Niklas Gustavsson's enhancement to have InputStream variants for DigestUtil's digest methods
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/codec/trunk@634903 13f79535-47bb-0310-9956-ffa450edef68
1 parent 4ac5444 commit 0752e9a

2 files changed

Lines changed: 195 additions & 7 deletions

File tree

src/java/org/apache/commons/codec/digest/DigestUtils.java

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717

1818
package org.apache.commons.codec.digest;
1919

20+
import java.io.IOException;
21+
import java.io.InputStream;
2022
import java.security.MessageDigest;
2123
import java.security.NoSuchAlgorithmException;
2224

@@ -30,6 +32,8 @@
3032
*/
3133
public class DigestUtils {
3234

35+
private static final int STREAM_BUFFER_LENGTH = 1024;
36+
3337
/**
3438
* Returns a <code>MessageDigest</code> for the given <code>algorithm</code>.
3539
*
@@ -115,6 +119,26 @@ private static MessageDigest getShaDigest() {
115119
return getDigest("SHA");
116120
}
117121

122+
/**
123+
* Read through an InputStream and returns the digest for the data
124+
*
125+
* @param digest The MessageDigest to use (e.g. MD5)
126+
* @param data Data to digest
127+
* @return MD5 digest
128+
* @throws IOException On error reading from the stream
129+
*/
130+
private static byte[] digest(MessageDigest digest, InputStream data) throws IOException {
131+
byte[] buffer = new byte[STREAM_BUFFER_LENGTH];
132+
int read = data.read(buffer, 0, STREAM_BUFFER_LENGTH);
133+
134+
while(read > -1) {
135+
digest.update(buffer, 0, read);
136+
read = data.read(buffer, 0, STREAM_BUFFER_LENGTH);
137+
}
138+
139+
return digest.digest();
140+
}
141+
118142
/**
119143
* Calculates the MD5 digest and returns the value as a 16 element <code>byte[]</code>.
120144
*
@@ -126,6 +150,18 @@ public static byte[] md5(byte[] data) {
126150
return getMd5Digest().digest(data);
127151
}
128152

153+
/**
154+
* Calculates the MD5 digest and returns the value as a 16 element <code>byte[]</code>.
155+
*
156+
* @param data
157+
* Data to digest
158+
* @return MD5 digest
159+
* @throws IOException On error reading from the stream
160+
*/
161+
public static byte[] md5(InputStream data) throws IOException {
162+
return digest(getMd5Digest(), data);
163+
}
164+
129165
/**
130166
* Calculates the MD5 digest and returns the value as a 16 element <code>byte[]</code>.
131167
*
@@ -159,6 +195,18 @@ public static String md5Hex(String data) {
159195
return new String(Hex.encodeHex(md5(data)));
160196
}
161197

198+
/**
199+
* Calculates the MD5 digest and returns the value as a 32 character hex string.
200+
*
201+
* @param data
202+
* Data to digest
203+
* @return MD5 digest as a hex string
204+
* @throws IOException On error reading from the stream
205+
*/
206+
public static String md5Hex(InputStream data) throws IOException {
207+
return new String(Hex.encodeHex(md5(data)));
208+
}
209+
162210
/**
163211
* Calculates the SHA-1 digest and returns the value as a <code>byte[]</code>.
164212
*
@@ -181,6 +229,18 @@ public static byte[] sha(String data) {
181229
return sha(data.getBytes());
182230
}
183231

232+
/**
233+
* Calculates the SHA-1 digest and returns the value as a <code>byte[]</code>.
234+
*
235+
* @param data
236+
* Data to digest
237+
* @return SHA-1 digest
238+
* @throws IOException On error reading from the stream
239+
*/
240+
public static byte[] sha(InputStream data) throws IOException {
241+
return digest(getShaDigest(), data);
242+
}
243+
184244
/**
185245
* Calculates the SHA-256 digest and returns the value as a <code>byte[]</code>.
186246
* <p>
@@ -209,6 +269,21 @@ public static byte[] sha256(String data) {
209269
return sha256(data.getBytes());
210270
}
211271

272+
/**
273+
* Calculates the SHA-256 digest and returns the value as a <code>byte[]</code>.
274+
* <p>
275+
* Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
276+
* </p>
277+
*
278+
* @param data
279+
* Data to digest
280+
* @return SHA-256 digest
281+
* @throws IOException On error reading from the stream
282+
*/
283+
public static byte[] sha256(InputStream data) throws IOException {
284+
return digest(getSha256Digest(), data);
285+
}
286+
212287
/**
213288
* Calculates the SHA-256 digest and returns the value as a hex string.
214289
* <p>
@@ -237,6 +312,21 @@ public static String sha256Hex(String data) {
237312
return new String(Hex.encodeHex(sha256(data)));
238313
}
239314

315+
/**
316+
* Calculates the SHA-256 digest and returns the value as a hex string.
317+
* <p>
318+
* Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
319+
* </p>
320+
*
321+
* @param data
322+
* Data to digest
323+
* @return SHA-256 digest as a hex string
324+
* @throws IOException On error reading from the stream
325+
*/
326+
public static String sha256Hex(InputStream data) throws IOException {
327+
return new String(Hex.encodeHex(sha256(data)));
328+
}
329+
240330
/**
241331
* Calculates the SHA-384 digest and returns the value as a <code>byte[]</code>.
242332
* <p>
@@ -265,6 +355,21 @@ public static byte[] sha384(byte[] data) {
265355
public static byte[] sha384(String data) {
266356
return sha384(data.getBytes());
267357
}
358+
359+
/**
360+
* Calculates the SHA-384 digest and returns the value as a <code>byte[]</code>.
361+
* <p>
362+
* Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
363+
* </p>
364+
*
365+
* @param data
366+
* Data to digest
367+
* @return SHA-384 digest
368+
* @throws IOException On error reading from the stream
369+
*/
370+
public static byte[] sha384(InputStream data) throws IOException {
371+
return digest(getSha384Digest(), data);
372+
}
268373

269374
/**
270375
* Calculates the SHA-384 digest and returns the value as a hex string.
@@ -294,6 +399,21 @@ public static String sha384Hex(String data) {
294399
return new String(Hex.encodeHex(sha384(data)));
295400
}
296401

402+
/**
403+
* Calculates the SHA-384 digest and returns the value as a hex string.
404+
* <p>
405+
* Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
406+
* </p>
407+
*
408+
* @param data
409+
* Data to digest
410+
* @return SHA-384 digest as a hex string
411+
* @throws IOException On error reading from the stream
412+
*/
413+
public static String sha384Hex(InputStream data) throws IOException {
414+
return new String(Hex.encodeHex(sha384(data)));
415+
}
416+
297417
/**
298418
* Calculates the SHA-512 digest and returns the value as a <code>byte[]</code>.
299419
* <p>
@@ -322,6 +442,21 @@ public static byte[] sha512(String data) {
322442
return sha512(data.getBytes());
323443
}
324444

445+
/**
446+
* Calculates the SHA-512 digest and returns the value as a <code>byte[]</code>.
447+
* <p>
448+
* Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
449+
* </p>
450+
*
451+
* @param data
452+
* Data to digest
453+
* @return SHA-512 digest
454+
* @throws IOException On error reading from the stream
455+
*/
456+
public static byte[] sha512(InputStream data) throws IOException {
457+
return digest(getSha512Digest(), data);
458+
}
459+
325460
/**
326461
* Calculates the SHA-512 digest and returns the value as a hex string.
327462
* <p>
@@ -350,6 +485,21 @@ public static String sha512Hex(String data) {
350485
return new String(Hex.encodeHex(sha512(data)));
351486
}
352487

488+
/**
489+
* Calculates the SHA-512 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-512 digest as a hex string
497+
* @throws IOException On error reading from the stream
498+
*/
499+
public static String sha512Hex(InputStream data) throws IOException {
500+
return new String(Hex.encodeHex(sha512(data)));
501+
}
502+
353503
/**
354504
* Calculates the SHA-1 digest and returns the value as a hex string.
355505
*
@@ -371,4 +521,16 @@ public static String shaHex(byte[] data) {
371521
public static String shaHex(String data) {
372522
return new String(Hex.encodeHex(sha(data)));
373523
}
524+
525+
/**
526+
* Calculates the SHA-1 digest and returns the value as a hex string.
527+
*
528+
* @param data
529+
* Data to digest
530+
* @return SHA-1 digest as a hex string
531+
* @throws IOException On error reading from the stream
532+
*/
533+
public static String shaHex(InputStream data) throws IOException {
534+
return new String(Hex.encodeHex(sha(data)));
535+
}
374536
}

src/test/org/apache/commons/codec/digest/DigestUtilsTest.java

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@
1717

1818
package org.apache.commons.codec.digest;
1919

20+
import java.io.ByteArrayInputStream;
21+
import java.io.IOException;
22+
import java.util.Random;
23+
2024
import junit.framework.TestCase;
2125

2226
/**
@@ -27,6 +31,15 @@
2731
*/
2832
public class DigestUtilsTest extends TestCase {
2933

34+
private byte[] testData = new byte[1024*1024];
35+
36+
/* (non-Javadoc)
37+
* @see junit.framework.TestCase#setUp()
38+
*/
39+
protected void setUp() throws Exception {
40+
new Random().nextBytes(testData);
41+
}
42+
3043
public void testInternalNoSuchAlgorithmException() {
3144
try {
3245
DigestUtils.getDigest("Bogus Bogus");
@@ -36,7 +49,7 @@ public void testInternalNoSuchAlgorithmException() {
3649
}
3750
}
3851

39-
public void testMd5Hex() {
52+
public void testMd5Hex() throws IOException {
4053
// Examples from RFC 1321
4154
assertEquals("d41d8cd98f00b204e9800998ecf8427e", DigestUtils.md5Hex(""));
4255

@@ -55,8 +68,11 @@ public void testMd5Hex() {
5568
assertEquals(
5669
"57edf4a22be3c955ac49da2e2107b67a",
5770
DigestUtils.md5Hex("1234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890"));
58-
}
5971

72+
assertEquals(DigestUtils.md5Hex(testData),
73+
DigestUtils.md5Hex(new ByteArrayInputStream(testData)));
74+
}
75+
6076
/**
6177
* An MD5 hash converted to hex should always be 32 characters.
6278
*/
@@ -83,17 +99,20 @@ public void testMD5Length() {
8399
assertEquals(16, hash.length);
84100
}
85101

86-
public void testSha256() {
102+
public void testSha256() throws IOException {
87103
// Examples from FIPS 180-2
88104
assertEquals("ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad",
89105
DigestUtils.sha256Hex("abc"));
90106
assertEquals("ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad",
91107
DigestUtils.sha256Hex("abc".getBytes()));
92108
assertEquals("248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1",
93109
DigestUtils.sha256Hex("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"));
110+
111+
assertEquals(DigestUtils.sha256Hex(testData),
112+
DigestUtils.sha256Hex(new ByteArrayInputStream(testData)));
94113
}
95114

96-
public void testSha384() {
115+
public void testSha384() throws IOException {
97116
// Examples from FIPS 180-2
98117
assertEquals("cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed" +
99118
"8086072ba1e7cc2358baeca134c825a7",
@@ -105,9 +124,11 @@ public void testSha384() {
105124
"fcc7c71a557e2db966c3e9fa91746039",
106125
DigestUtils.sha384Hex("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn" +
107126
"hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"));
127+
assertEquals(DigestUtils.sha384Hex(testData),
128+
DigestUtils.sha384Hex(new ByteArrayInputStream(testData)));
108129
}
109130

110-
public void testSha512() {
131+
public void testSha512() throws IOException {
111132
// Examples from FIPS 180-2
112133
assertEquals("ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a" +
113134
"2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f",
@@ -119,9 +140,11 @@ public void testSha512() {
119140
"501d289e4900f7e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909",
120141
DigestUtils.sha512Hex("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn" +
121142
"hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"));
122-
}
143+
assertEquals(DigestUtils.sha512Hex(testData),
144+
DigestUtils.sha512Hex(new ByteArrayInputStream(testData)));
145+
}
123146

124-
public void testShaHex() {
147+
public void testShaHex() throws IOException {
125148
// Examples from FIPS 180-1
126149
assertEquals("a9993e364706816aba3e25717850c26c9cd0d89d", DigestUtils.shaHex("abc"));
127150

@@ -130,5 +153,8 @@ public void testShaHex() {
130153
assertEquals(
131154
"84983e441c3bd26ebaae4aa1f95129e5e54670f1",
132155
DigestUtils.shaHex("abcdbcdecdefdefgefghfghighij" + "hijkijkljklmklmnlmnomnopnopq"));
156+
assertEquals(DigestUtils.shaHex(testData),
157+
DigestUtils.shaHex(new ByteArrayInputStream(testData)));
158+
133159
}
134160
}

0 commit comments

Comments
 (0)