【轉】Java計算檔案的hash值

來源:互聯網
上載者:User

標籤:comm   stringbu   ref   static   data   轉換   .net   md5值   return   

原文地址:http://blog.csdn.net/qq_25646191/article/details/78863110

如何知道一個檔案是否改變了呢?當然是用比較檔案hash值的方法,檔案hash又叫檔案簽名,檔案中哪怕一個bit位被改變了,檔案hash就會不同。

比較常用的檔案hash演算法有MD5和SHA-1。
我用的是MD5演算法,java中,計算MD5可以用MessageDigest這個類。

下面是代碼:

 

[java] view plain copy
  1. package com.test;    
  2.     
  3. import java.io.FileInputStream;    
  4. import java.io.FileNotFoundException;    
  5. import java.io.InputStream;    
  6. import java.math.BigInteger;    
  7. import java.security.MessageDigest;    
  8.     
  9. public class MD5Util {    
  10.         
  11.     public static void main(String[] args) {    
  12.         try {    
  13.             //此處我測試的是我本機jdk源碼檔案的MD5值   
  14.             String filePath = "C:\\Program Files\\Java\\jdk1.7.0_45\\src.zip";  
  15.               
  16.             String md5Hashcode = md5HashCode(filePath);  
  17.             String md5Hashcode32 = md5HashCode32(filePath);    
  18.               
  19.             System.out.println(md5Hashcode + ":檔案的md5值");    
  20.             System.out.println(md5Hashcode32+":檔案32位的md5值");   
  21.               
  22.             //System.out.println(-100 & 0xff);  
  23.         } catch (FileNotFoundException e) {    
  24.             e.printStackTrace();    
  25.         }    
  26.     }    
  27.       
  28.     /** 
  29.      * 擷取檔案的md5值 ,有可能不是32位 
  30.      * @param filePath  檔案路徑 
  31.      * @return 
  32.      * @throws FileNotFoundException 
  33.      */  
  34.     public static String md5HashCode(String filePath) throws FileNotFoundException{    
  35.         FileInputStream fis = new FileInputStream(filePath);    
  36.         return md5HashCode(fis);    
  37.     }    
  38.       
  39.     /** 
  40.      * 保證檔案的MD5值為32位 
  41.      * @param filePath  檔案路徑 
  42.      * @return 
  43.      * @throws FileNotFoundException 
  44.      */  
  45.     public static String md5HashCode32(String filePath) throws FileNotFoundException{    
  46.         FileInputStream fis = new FileInputStream(filePath);    
  47.         return md5HashCode32(fis);    
  48.     }    
  49.       
  50.     /** 
  51.      * java擷取檔案的md5值   
  52.      * @param fis 輸入資料流 
  53.      * @return 
  54.      */  
  55.     public static String md5HashCode(InputStream fis) {    
  56.         try {    
  57.             //拿到一個MD5轉換器,如果想使用SHA-1或SHA-256,則傳入SHA-1,SHA-256    
  58.             MessageDigest md = MessageDigest.getInstance("MD5");   
  59.               
  60.             //分多次將一個檔案讀入,對於大型檔案而言,比較推薦這種方式,佔用記憶體比較少。  
  61.             byte[] buffer = new byte[1024];    
  62.             int length = -1;    
  63.             while ((length = fis.read(buffer, 0, 1024)) != -1) {    
  64.                 md.update(buffer, 0, length);    
  65.             }    
  66.             fis.close();  
  67.             //轉換並返回包含16個元素位元組數組,返回數值範圍為-128到127  
  68.             byte[] md5Bytes  = md.digest();  
  69.             BigInteger bigInt = new BigInteger(1, md5Bytes);//1代表絕對值   
  70.             return bigInt.toString(16);//轉換為16進位  
  71.         } catch (Exception e) {    
  72.             e.printStackTrace();    
  73.             return "";    
  74.         }    
  75.     }    
  76.       
  77.     /** 
  78.      * java計算檔案32位md5值 
  79.      * @param fis 輸入資料流 
  80.      * @return 
  81.      */  
  82.     public static String md5HashCode32(InputStream fis) {  
  83.         try {  
  84.             //拿到一個MD5轉換器,如果想使用SHA-1或SHA-256,則傳入SHA-1,SHA-256    
  85.             MessageDigest md = MessageDigest.getInstance("MD5");  
  86.               
  87.             //分多次將一個檔案讀入,對於大型檔案而言,比較推薦這種方式,佔用記憶體比較少。  
  88.             byte[] buffer = new byte[1024];  
  89.             int length = -1;  
  90.             while ((length = fis.read(buffer, 0, 1024)) != -1) {  
  91.                 md.update(buffer, 0, length);  
  92.             }  
  93.             fis.close();  
  94.               
  95.             //轉換並返回包含16個元素位元組數組,返回數值範圍為-128到127  
  96.             byte[] md5Bytes  = md.digest();  
  97.             StringBuffer hexValue = new StringBuffer();  
  98.             for (int i = 0; i < md5Bytes.length; i++) {  
  99.                 int val = ((int) md5Bytes[i]) & 0xff;//解釋參見最下方  
  100.                 if (val < 16) {  
  101.                     /** 
  102.                      * 如果小於16,那麼val值的16進位形式必然為一位, 
  103.                      * 因為十進位0,1...9,10,11,12,13,14,15 對應的 16進位為 0,1...9,a,b,c,d,e,f; 
  104.                      * 此處高位補0。 
  105.                      */  
  106.                     hexValue.append("0");  
  107.                 }  
  108.                 //這裡藉助了Integer類的方法實現16進位的轉換   
  109.                 hexValue.append(Integer.toHexString(val));  
  110.             }  
  111.             return hexValue.toString();  
  112.         } catch (Exception e) {  
  113.             e.printStackTrace();  
  114.             return "";  
  115.         }  
  116.     }  
  117.       
  118.     /** 
  119.      * 方法md5HashCode32 中     ((int) md5Bytes[i]) & 0xff   操作的解釋: 
  120.      * 在Java語言中涉及到位元組byte數組資料的一些操作時,經常看到 byte[i] & 0xff這樣的操作,這裡就記錄總結一下這裡包含的意義:  
  121.      * 1、0xff是16進位(十進位是255),它預設為整形,二進位位為32位,最低八位是“1111 1111”,其餘24位都是0。  
  122.      * 2、&運算: 如果2個bit都是1,則得1,否則得0;  
  123.      * 3、byte[i] & 0xff:首先,這個操作一般都是在將byte資料轉成int或者其他整形資料的過程中;使用了這個操作,最終的整形資料只有低8位有資料,其他位元都為0。  
  124.      * 4、這個操作得出的整形資料都是大於等於0並且小於等於255的 
  125.      */  
  126.     
  127. }    

 

運行結果如:

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

方法很多,其實有一個挺簡單的方法,不需要另外安裝什麼軟體。

使用windows內建的命令即可:certutil -hashfile [檔案路徑] MD5,

例子如下:

 

【轉】Java計算檔案的hash值

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.