Rectangle 27 0

java Calculate multiple checksums from the same InputStream using DigestInputStream?


DigestInputStream
DigestInputStream shaStream = new DigestInputStream(
    inStream, MessageDigest.getInstance("SHA-1"));
DigestInputStream md5Stream = new DigestInputStream(
    shaStream, MessageDigest.getInstance("MD5"));
// read from final stream
byte[] shaDigest = shaStream.getDigest().digest();
byte[] md5Digest = md5Stream.getDigest().digest();

Thank you very much for this excellent answer! What a great hack!

Note
Rectangle 27 0

java Calculate multiple checksums from the same InputStream using DigestInputStream?


MessageDigest sha = MessageDigest.getInstance("SHA-1");
MessageDigest md5 = MessageDigest.getInstance("MD5");
InputStream input = ...;
byte[] buffer = new byte[BUFFER_SIZE];
int len;
while((len = input.read(buffer)) >= 0)
{
    sha.update(buffer,0,len);
    md5.update(buffer,0,len);
    ...
}
byte[] shaDigest = sha.digest();
byte[] md5Digest = md5.digest();

Jim, could you show me an example, please? Also, does this mean that each digest will be keeping in memory the read bytes from the InputStream?

No, each digest will keep only its own work area. You will be reading the data stream once.

Right... I see what you mean now. I have to update the digest upon every read.

The Javadoc is pretty clear. You can use clone only to calculate different intermediate digests using the same algorithm. You cannot use DigestInputStream to calculate different digest algorithms without reading the stream multiple times. You must use a regular InputStream and multiple MessageDigest objects; read the data once, passing each buffer to all MessageDigest objects to get multiple digests with different algorithms.

You could easily encapsulate this in your own variant of DigestInputStream, say MultipleDigestInputStream that follows the same general approach but accepts a collection of MessageDigest objects or algorithm names.

Note