3

InputStreamを使用して、同じものに基づいて複数のダイジェスト (md5、sha1、gpg) を読み取る方法を見つけようとしていDigestInputStreamます。ドキュメントで確認したところ、ダイジェストを複製することで可能のようです。誰かがこれを説明してもらえますか?

チェックサムを計算するためにストリームを再読み込みしたくありません。

4

2 に答える 2

13

DigestInputStreamaDigestInputStreamなどを再帰的にラップできます。

DigestInputStream shaStream = new DigestInputStream(
    inStream, MessageDigest.getInstance("SHA-1"));
DigestInputStream md5Stream = new DigestInputStream(
    shaStream, MessageDigest.getInstance("MD5"));
// VERY IMPORTANT: read from final stream since it's FilterInputStream
byte[] shaDigest = shaStream.getMessageDigest().digest();
byte[] md5Digest = md5Stream.getMessageDigest().digest();
于 2013-10-10T19:13:10.300 に答える
2

Javadoc は非常に明確です。clone only を使用して、同じアルゴリズムを使用して異なる中間ダイジェストを計算できます。DigestInputStreamストリームを複数回読み取らずに、さまざまなダイジェスト アルゴリズムを計算するために使用することはできません。InputStream通常の複数のMessageDigestオブジェクトを使用する必要があります。データを一度読み取り、各バッファをすべてのMessageDigestオブジェクトに渡して、異なるアルゴリズムで複数のダイジェストを取得します。

これは、同じ一般的なアプローチに従いますが、オブジェクトまたはアルゴリズム名のコレクションを受け入れるなどDigestInputStream、独自のバリアントで簡単にカプセル化できます。MultipleDigestInputStreamMessageDigest

Pseudojava (エラーハンドリング省略)

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();
于 2013-10-10T16:08:53.753 に答える