Corrections to Chapter 10 of Java I/O, Cryptographic Streams

p. 221: In the top box of Figure 10-1,

MessageDigest md = MessageDigest(getInstance{ algorithm })

should be

MessageDigest md = MessageDigest.getInstance(algorithm)

The corrected figure looks like this:

flow chart demonstrating how to compute a message digest in Java

p. 222: The last line of Example 10-1 should construct the BigInteger for result, not data. That is.

System.out.println(new BigInteger(result));

Once this fix is made, the output should look like this:

% java URLDigest
-24 86 -50 -110 47 -95 12 -95 -36 38 -110 -10 -53 -33 -80 -101 -33 74 -76 41
p. 224, 225: The description of the third digest() method on pp. 224-225 is incorrect. Replace that section with the following:

Finishing the Digest

In general, digest algorithms cannot finish the calculation and return the digest until the last byte is received. When you are ready to finish the calculation and receive the digest, you invoke one of three overloaded digest() methods:

public byte[] digest()
public byte[] digest(byte[] input)
public int digest(byte[] output, int offset, int length) throws DigestException

The first digest() method simply returns the digest as an array of bytes based on the data that was already passed in through update(). For example,

byte[] result = sha.digest();

The second digest() method receives one last chunk of data in the input array, then returns the digest. The third digest() method calculates the digest and places it in the array output beginning at offset and continuing for at most length bytes, then returns the number of bytes in the digest. If there are more than length bytes in the digest a DigestException is thrown. After you've called digest(), the MessageDigest object is reset so it can be reused to calculate a new digest.

p. 227: In the output at the top of the page, is up to date should be is up to date. (Blame it on a an overly aggressive search and replace.)

p. 228: At the top of the page replace the first paragraph and line of code with this (which is accurate as of the release version of the JDK 1.2)

This returns a string in the form "algorithm Message Digest from provider, <initialized>" or "algorithm Message Digest from provider, <in progress>". For example,

SHA Message Digest from SUN, <initialized>

p. 254: Figure 10-3 has the wrong capitalization of GZipOutputStream. It should be GZIPOutputStream.

p. 255: In the second paragraph, change "Like all filter stream constructors, this constructor also takes another input stream as an argument:" to "Like all filter input stream constructors, this constructor takes another input stream as an argument:"

p. 257: The first class declaration on the page says CipherInputStream instead of CipherOutputStream. The declaration should be

public class CipherOutputStream extends FilterOutputStream

In the following paragraph, change "Like all filter stream constructors, this constructor also takes another input stream as an argument:" to "Like all filter output stream constructors, this constructor takes another output stream as an argument:"

p. 263: In the third code line on this page, it's helpful to add a test that the password is not the empty string. It doesn't matter for this application alone, but it will later. So change

if (password != null) {


if (password != null && !password.equals("")) {

[ Java I/O Corrections | Java I/O Home Page | Table of Contents | Examples | Order from Amazon ] ]

Copyright 1999, 2001, 2003 Elliotte Rusty Harold
Last Modified January 3, 2003