JAVA中獲取文件MD5值的四種方法


JAVA中獲取文件MD5值的四種方法

  JAVA中獲取文件MD5值的四種方法其實都很類似,因爲核心都是通過JAVA自帶的MessageDigest類來實現。獲取文件MD5值主要分爲三個步驟,第一步獲取文件的byte信息,第二步通過MessageDigest類進行MD5加密,第三步轉換成16進制的MD5碼值。幾種方法的不同點主要在第一步和第三步上。具體可以看下面的例子:

 

方法一、

複製代碼
 1   private final static String[] strHex = { "0", "1", "2", "3", "4", "5",
 2             "6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };
 3 
 4     public static String getMD5One(String path) {
 5         StringBuffer sb = new StringBuffer();
 6         try {
 7             MessageDigest md = MessageDigest.getInstance("MD5");
 8             byte[] b = md.digest(FileUtils.readFileToByteArray(new File(path)));
 9             for (int i = 0; i < b.length; i++) {
10                 int d = b[i];
11                 if (d < 0) {
12                     d += 256;
13                 }
14                 int d1 = d / 16;
15                 int d2 = d % 16;
16                 sb.append(strHex[d1] + strHex[d2]);
17             }
18         } catch (NoSuchAlgorithmException e) {
19             e.printStackTrace();
20         } catch (IOException e) {
21             e.printStackTrace();
22         }
23         return sb.toString();
24     }
複製代碼

  方法一是比較原始的一種實現方法,首先將文件一次性讀入內存,然後通過MessageDigest進行MD5加密,最後再手動將其轉換爲16進制的MD5值。

 

方法二、

複製代碼
 1   public static String getMD5Two(String path) {
 2         StringBuffer sb = new StringBuffer("");
 3         try {
 4             MessageDigest md = MessageDigest.getInstance("MD5");
 5             md.update(FileUtils.readFileToByteArray(new File(path)));
 6             byte b[] = md.digest();
 7             int d;
 8             for (int i = 0; i < b.length; i++) {
 9                 d = b[i];
10                 if (d < 0) {
11                     d = b[i] & 0xff;
12                     // 與上一行效果等同
13                     // i += 256;
14                 }
15                 if (d < 16)
16                     sb.append("0");
17                 sb.append(Integer.toHexString(d));
18             }
19         } catch (NoSuchAlgorithmException e) {
20             e.printStackTrace();
21         } catch (IOException e) {
22             e.printStackTrace();
23         }
24         return sb.toString();
25     }
複製代碼

  方法二與方法一不同的地方主要是在步驟三,這裏藉助了Integer類的方法實現16進制的轉換,比方法一更簡潔一些。PS:JAVA中byte是有負數的,代碼中&0xff的操作與計算機中數據存儲的原理有關,即負數存儲的是二進制的補碼,有興趣的童鞋可以挖一下,這裏不展開說。

 

方法三、

複製代碼
 1   public static String getMD5Three(String path) {
 2         BigInteger bi = null;
 3         try {
 4             byte[] buffer = new byte[8192];
 5             int len = 0;
 6             MessageDigest md = MessageDigest.getInstance("MD5");
 7             File f = new File(path);
 8             FileInputStream fis = new FileInputStream(f);
 9             while ((len = fis.read(buffer)) != -1) {
10                 md.update(buffer, 0, len);
11             }
12             fis.close();
13             byte[] b = md.digest();
14             bi = new BigInteger(1, b);
15         } catch (NoSuchAlgorithmException e) {
16             e.printStackTrace();
17         } catch (IOException e) {
18             e.printStackTrace();
19         }
20         return bi.toString(16);
21     }
複製代碼

  方法三與前面兩個方法相比,在讀入文件信息上有點不同。這裏是分多次將一個文件讀入,對於大型文件而言,比較推薦這種方式,佔用內存比較少。步驟三則是通過BigInteger類提供的方法進行16進制的轉換,與方法二類似。

 

方法四、

1   DigestUtils.md5Hex(new FileInputStream(path));

  方法四應該是最便捷的吧,哈哈,好東西要留在最後,如果你只需要使用標準的MD5,其實一行代碼就夠了,JAVA自帶的commons-codec包就提供了獲取16進制MD5值的方法。其底層實現上,也是分多次將一個文件讀入,類似方法三。所以性能上也不錯。

 

  總結:其實方法都是類似的,推薦使用方法四,簡潔且性能不錯,當然,如果要做一些調整什麼的,可以根據自己的需求進行方法的選擇。

PS:其實還有一個重點,就是如何知道自己生成的MD5值是否正確呢?

  方法很多,其實有一個挺簡單的方法,不需要另外安裝什麼軟件。使用windows自帶的命令即可:certutil -hashfile [文件路徑] MD5,例子如下:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章