2013-07-02 33 views
0

我在嘗試檢查文件的MD5哈希時收到錯誤。檢查文件的MD5

文件,notice.txt有以下內容:

My name is sanjay yadav . i am in btech computer science .>> 

當我與onlineMD5.com網上查它給了MD5爲:90F450C33FAC09630D344CBA9BF80471

我的程序的輸出是:

My name is sanjay yadav . i am in btech computer science . 
Read 58 bytes 
d41d8cd98f00b204e9800998ecf8427e 

這裏是我的代碼:

import java.io.*; 
import java.math.BigInteger; 
import java.security.DigestException; 
import java.security.MessageDigest; 
import java.security.NoSuchAlgorithmException; 

public class MsgDgt { 
    public static void main(String[] args) throws IOException, DigestException, NoSuchAlgorithmException { 

     FileInputStream inputstream = null; 
     byte[] mybyte = new byte[1024]; 

     inputstream = new FileInputStream("e://notice.txt"); 
     int total = 0; 
     int nRead = 0; 
     MessageDigest md = MessageDigest.getInstance("MD5"); 
     while ((nRead = inputstream.read(mybyte)) != -1) { 
      System.out.println(new String(mybyte)); 
      total += nRead; 
      md.update(mybyte, 0, nRead); 
     } 

     System.out.println("Read " + total + " bytes"); 
     md.digest(); 
     System.out.println(new BigInteger(1, md.digest()).toString(16)); 
    } 
} 
+0

可能的[在Java中獲取文件的MD5校驗和]中的重複(http://stackoverflow.com/questions/ 304268/getting-a-files-md5-checksum-in-java) – Simon

+0

我現在不會依賴那個網站..我認爲輸出2f4c6a40682161e5b01c24d5aa896da0是正確的......你錯過了最後一個零..(請檢查它)。內容是「我的名字是sanjay yadav,我在btech計算機科學。」 – Bitopan

回答

1

有一個在你的代碼中的錯誤我相信在線工具正在給出錯誤的答案。在這裏,您目前計算兩次摘要:

md.digest(); 
System.out.println(new BigInteger(1, md.digest()).toString(16)); 

每次調用digest()時間,它重置內部狀態。您應該刪除第一個電話digest()。這則留給你這是摘要:

2f4c6a40682161e5b01c24d5aa896da0 

這是同樣的結果,我從C#弄的,我相信這是正確的。我不知道爲什麼在線檢查器給出的結果不正確。 (如果你把它放到同一部位的文本部分,它提供了正確的結果。)

上驗證碼的其他幾個要點,但:

  • 您目前正在使用的平臺將字節轉換爲字符串時的默認編碼。我強烈勸阻你這樣做。
  • 您目前正在將整個緩衝區轉換爲字符串,而不是隻讀取您已讀取的位。
  • 我不喜歡使用BigInteger作爲將二進制數據轉換爲十六進制的方式。你可能需要用0填充它,它基本上不是該類設計的。使用專用的十六進制轉換類,例如來自Apache Commons Codec(或爲此目的提供獨立類的各種Stack Overflow答案)。
  • 你沒有關閉你的輸入流。您應該在finally塊中執行此操作,或者在Java 7中使用try-with-resources語句執行此操作。
+0

我已經cheched它,它正在工作。 – Bitopan

+0

我現在不會依賴那個網站..我認爲輸出2f4c6a40682161e5b01c24d5aa896da0是正確的......你錯過了最後一個零..(請檢查它)。內容是「我的名字是sanjay yadav,我在btech計算機科學。」 – Bitopan

+0

@Bitopan:是的,只是C&P錯誤。 –

0

我用這個函數:

public static String md5Hash(File file) { 
    try { 
     MessageDigest md = MessageDigest.getInstance("MD5"); 
     InputStream is = new FileInputStream(file); 
     byte[] buffer = new byte[1024]; 

     try { 
      is = new DigestInputStream(is, md); 

      while (is.read(buffer) != -1) { } 
     } finally { 
      is.close(); 
     } 

     byte[] digest = md.digest(); 

     BigInteger bigInt = new BigInteger(1, digest); 
     String output = bigInt.toString(16); 
     while (output.length() < 32) { 
      output = "0" + output; 
     } 

     return output; 
    } catch (NoSuchAlgorithmException e) { 
     e.printStackTrace(); 
    } catch (FileNotFoundException e) { 
     e.printStackTrace(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 

    return null; 
} 
+0

爲什麼要爲每個'read'調用創建一個新的字節數組?這對我來說似乎有些曲折 - 正如使用BigInteger進行十六進制轉換(而不是將字節數組轉換爲十六進制的代碼)。異常處理也令人擔憂... –

+0

其實,我現在不清楚現在想想它的全部功能。這是我在網上找到的一個例子。雖然,我不確定使用BigInteger的問題,但您會怎麼做?我完全同意字節數組聲明。 – Knossos

+0

我要麼使用Apache Commons Codec之類的東西,要麼在堆棧溢出中找到許多「如何將字節轉換爲十六進制」問題的答案。 –