Computing a MessageDigest Object

First create the message digest object, as in the following example:
MessageDigest sha = MessageDigest.getInstance("SHA-1");

This call assigns a properly initialized message digest object to the sha variable. The implementation implements the Secure Hash Algorithm (SHA-1), as defined in the National Institute for Standards and Technology's (NIST) FIPS 180-2 document. See Appendix A for a complete discussion of standard names and algorithms.

Next, suppose we have three byte arrays, i1, i2 and i3, which form the total input whose message digest we want to compute. This digest (or hash) could be calculated using the following calls:
sha.update(i1);
sha.update(i2);
sha.update(i3);
byte[] hash = sha.digest();
An equivalent alternative series of calls would be:
sha.update(i1);
sha.update(i2);
byte[] hash = sha.digest(i3);

After the message digest has been calculated, the message digest object is automatically reset and ready to receive new data and calculate its digest. All former state (that is the data supplied to update calls) is lost.

Some hash implementations might support intermediate hashes through cloning. Suppose we want to calculate separate hashes for:
  • i1
  • i1 and i2
  • i1, i2, and i3
A way to calculate the hashes is:
/* compute the hash for i1 */
sha.update(i1); 
byte[] i1Hash = sha.clone().digest();

/* compute the hash for i1 and i2 */
sha.update(i2); 
byte[] i12Hash = sha.clone().digest(); 

/* compute the hash for i1, i2 and i3 */
sha.update(i3); 
byte[] i123hash = sha.digest();
This code works only if the SHA-1 implementation is cloneable. While some implementations of message digests are cloneable, others are not. To determine whether or not cloning is possible, attempt to clone the MessageDigest object and catch the potential exception as follows:
try {
 // try and clone it
 /* compute the hash for i1 */
 sha.update(i1); 
 byte[] i1Hash = sha.clone().digest();
 . . .
 byte[] i123hash = sha.digest();
} catch (CloneNotSupportedException cnse) {
 // do something else, as in the next code example
}
If a message digest is not cloneable, you can compute intermediate digests by creating several digests. In this case, the number of intermediate digests to be computed must be known in advance:
MessageDigest sha1 = MessageDigest.getInstance("SHA-1");
MessageDigest sha12 = MessageDigest.getInstance("SHA-1"); 
MessageDigest sha123 = MessageDigest.getInstance("SHA-1");
byte[] i1Hash = sha1.digest(i1);
sha12.update(i1);
byte[] i12Hash = sha12.digest(i2);
sha123.update(i1);
sha123.update(i2);
byte[] i123Hash = sha123.digest(i3);