2

次のスニペットは両方ともsha-1合計を計算することになっています。しかし、同じファイルに対して、異なるsha-1合計を計算します。

//snippet1
byte[] byteArr = new byte[(int) uploadedFile.getLength()];
try {
 stream = new BufferedInputStream(uploadedFile.getInputStream());
 stream.read(byteArr);
 stream.close(); 
} catch (IOException e) {
 e.printStackTrace();
}
md = MessageDigest.getInstance("SHA-1"); 
byte[] sha1hash = new byte[40];
md.update(byteArr, 0, byteArr.length);
sha1hash = md.digest();

//snippet2
md = MessageDigest.getInstance("SHA-1");
InputStream is = uploadedFile.getInputStream();
try {
 is = new DigestInputStream(is, md);
} finally {
 try {
  is.close();
 } catch (IOException e) {
  e.printStackTrace();
 }
}
sha1hash = md.digest();

理由を説明できますか?

4

2 に答える 2

12

どちらのスニペットにもバグがあります。

  • 最初に切り取られたものは、ファイルから(事実上ランダムな)バイト数を読み取り、ファイル全体を読み取ることを保証するものではありません(詳細については、のJavaDocread()を参照してください)。

  • 2番目のスニップはInputStreamから何も読み取らないため、空のストリームのSHA-1を返します(0バイトの読み取り)。

于 2009-09-07T09:49:49.457 に答える
3

ここにバグがあります:

 stream = new BufferedInputStream(uploadedFile.getInputStream());
 stream.read(byteArr);
 stream.close(); 

このread()メソッドは、渡された配列を自動的に埋めません。任意のバイト数を読み取り、その数を返します。配列がいっぱいになるまで、返されたバイト数をループして合計する必要があります。

ほとんどの人が最初にそれを間違えますが、それが入力ストリームベースの方法が優れている理由の1つです(もう1つは、大きなファイルの場合、それらを完全にメモリに保持したくないということです)。

于 2009-09-07T09:50:39.370 に答える