1. 程式人生 > >Java對大檔案MD5解密詳解

Java對大檔案MD5解密詳解

        MD5是常用的加密演算法,也經常用於校驗資訊完整,如檔案的完整性。用術語講,MD5是一種訊息摘要演算法(Message Digest Algorithm)。另外還有一種常用的訊息摘要演算法SHA1。如果想了解這些的話,可以去百度百科:MD5、SHA1、訊息摘要演算法。

Java已經實現了MD5、SHA1演算法。利用java.security.MessageDigest類就可以獲取字串和檔案的MD5以及SHA1結果。

1.字串的MD5(下面的程式碼有詳細註釋)

  1. publicstatic String stringMD5(String input) {  
  2.    try {  
  3.       // 拿到一個MD5轉換器(如果想要SHA1引數換成”SHA1”)
  4.       MessageDigest messageDigest =MessageDigest.getInstance("MD5");  
  5.       // 輸入的字串轉換成位元組陣列
  6.       byte[] inputByteArray = input.getBytes();  
  7.       // inputByteArray是輸入字串轉換得到的位元組陣列
  8.       messageDigest.update(inputByteArray);  
  9.       // 轉換並返回結果,也是位元組陣列,包含16個元素
  10.       byte
    [] resultByteArray = messageDigest.digest();  
  11.       // 字元陣列轉換成字串返回
  12.       return byteArrayToHex(resultByteArray);  
  13.    } catch (NoSuchAlgorithmException e) {  
  14.       returnnull;  
  15.    }  
  16. }  


   //下面這個函式用於將位元組陣列換成成16進位制的字串

  1. publicstatic String byteArrayToHex(byte[] byteArray) {  
  2.    // 首先初始化一個字元陣列,用來存放每個16進位制字元
  3.    char[] hexDigits = {'0','1','2','3','4','5','6','7','8','9''A','B','C','D','E','F' };  
  4.    // new一個字元陣列,這個就是用來組成結果字串的(解釋一下:一個byte是八位二進位制,也就是2位十六進位制字元(2的8次方等於16的2次方))
  5.    char[] resultCharArray =newchar[byteArray.length * 2];  
  6.    // 遍歷位元組陣列,通過位運算(位運算效率高),轉換成字元放到字元陣列中去
  7.    int index = 0;  
  8.    for (byte b : byteArray) {  
  9.       resultCharArray[index++] = hexDigits[b>>> 4 & 0xf];  
  10.       resultCharArray[index++] = hexDigits[b& 0xf];  
  11.    }  
  12.    // 字元陣列組合成字串返回
  13.    returnnew String(resultCharArray);  


從上面程式碼可以看出,使用MessageDigest對字串進行MD5演算法的步驟是,先將字串轉換成位元組陣列,在進行MD5演算法,最後返回的也是一個位元組陣列,要我們自己轉成32位的字串。

2.檔案MD5

對檔案進行MD5也可以像字串MD5一樣的,首先要把檔案轉成位元組陣列,後面和字串MD5完全一樣。

但是如果是一個特別大的檔案,一下子把一個檔案的陣列全部讀到記憶體中,那麼估計記憶體也吃不消。

對於大檔案,可以使用DigestInputStream。

  1. publicstatic String fileMD5(String inputFile) throws IOException {  
  2.       // 緩衝區大小(這個可以抽出一個引數)
  3.       int bufferSize = 256 * 1024;  
  4.       FileInputStream fileInputStream = null;  
  5.       DigestInputStream digestInputStream = null;  
  6.       try {  
  7.          // 拿到一個MD5轉換器(同樣,這裡可以換成SHA1)
  8.          MessageDigest messageDigest =MessageDigest.getInstance("MD5");  
  9.          // 使用DigestInputStream
  10.          fileInputStream = new FileInputStream(inputFile);  
  11.          digestInputStream = new DigestInputStream(fileInputStream,messageDigest);  
  12.          // read的過程中進行MD5處理,直到讀完檔案
  13.          byte[] buffer =newbyte[bufferSize];  
  14.          while (digestInputStream.read(buffer) > 0);  
  15.          // 獲取最終的MessageDigest
  16.          messageDigest= digestInputStream.getMessageDigest();  
  17.          // 拿到結果,也是位元組陣列,包含16個元素
  18.          byte[] resultByteArray = messageDigest.digest();  
  19.          // 同樣,把位元組陣列轉換成字串
  20.          return byteArrayToHex(resultByteArray);  
  21.       } catch (NoSuchAlgorithmException e) {  
  22.          returnnull;  
  23.       } finally {  
  24.          try {  
  25.             digestInputStream.close();  
  26.          } catch (Exception e) {  
  27.          }  
  28.          try {  
  29.             fileInputStream.close();  
  30.          } catch (Exception e) {  
  31.          }  
  32.       }  
  33.    }  


   上面的方法本人親測過大小約4G的檔案,得出的MD5值和網上下載的一個MD5小工具得到的MD5值一樣,說明上面的方式沒有什麼問題。不過取大檔案的MD5很慢,4G的檔案跑一下要一分鐘(I5處理器 6G記憶體 64位XP系統 本本)。

附1:我在網上還看到一種給檔案MD5的方式

  1. publicstatic String getFileMD5String(File file) throws IOException{  
  2.  FileInputStream in = new FileInputStream(file);  
  3.  FileChannel ch =in.getChannel();  
  4.  MappedByteBuffer byteBuffer =ch.map(FileChannel.MapMode.READ_ONLY, 0,file.length());  
  5.  messagedigest.update(byteBuffer);  
  6.  return byteArrayToHex (messagedigest.digest());  
  7. }  

我也嘗試過這樣的方式,但是如果檔案大於2G,那麼這種方式會出現異常。所以不推薦。

附2:測試檔案MD5的main方法

  1. publicstaticvoid main(String[] args) {  
  2.   long startTime = System.currentTimeMillis();  
  3.   try {  
  4.     System.out.println(fileMD5("E:/軟體/VS2008ProEdition90DayTrialCHSX1435983.iso"));  
  5.   } catch (IOException e) {  
  6.     e.printStackTrace();  
  7.   }  
  8.   long endTime = System.currentTimeMillis();  
  9.   System.out.println((endTime - startTime)/1000);  
  10. }  

相關推薦

Java檔案MD5解密

        MD5是常用的加密演算法,也經常用於校驗資訊完整,如檔案的完整性。用術語講,MD5是一種訊息摘要演算法(Message Digest Algorithm)。另外還有一種常用的訊息摘要演算法SHA1。如果想了解這些的話,可以去百度百科:MD5、SHA1、訊息

Java象和類的

htc db2 ucs docs em1 mvp ini ndt ecs 琴7A0坎4純3硬si藕菜時http://docstore.docin.com/xpyd645 膊9強4埔cs黑依oehttp://www.docin.com/nir7778 R7E20wm8

Java檔案的高效讀取方法

1、檔案流   現在讓我們看下這種解決方案——我們將使用java.util.Scanner類掃描檔案的內容,一行一行連續地讀取: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 FileInputS

獲取檔案MD5值(JAVA

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

Java實現的SFTP(檔案上傳篇)

JSch是Java Secure Channel的縮寫。JSch是一個SSH2的純Java實現。它允許你連線到一個SSH伺服器,並且可以使用埠轉發,X11轉發,檔案傳輸等,當然你也可以整合它的功能到你自己的應用程式。 本文只介紹如何使用JSch實現的SFTP功能

Java程式設計中常用的集合 你非常有用

Java中的集合概述 集合是一個容器,用來存放引用型別的資料,在java.util包下。 Java中的集合主要有3種類型: List介面: 是一個有序集合,可以放重複的資料。 Set介面: 是一個無序集合,不允許放重複的資料。 Map介面: 是一個無序集合,集合

Java合併壓多省話單gz檔案,程式碼涉及壓、合併、刪除、複製邏輯

專案要求是能定時解壓gz檔案,並按照省將檔案成一個大檔案,程式碼實現功能:按照gz壓縮包的路徑格式解壓檔案,最後將檔案合併成按照省份名稱排放的大檔案,專案用log4j記錄日誌,用Java定時器實現定時解壓合併,並且刪除解壓出來的小檔案,同時也刪除解壓目錄下的壓縮包,並將壓縮

java獲取檔案MD5、SHA1,CRC32碼

import org.apache.commons.codec.digest.DigestUtils; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.

UNIX下利用OpenSSL檔案進行AES加解密

      由於專案需要檔案傳輸過程中對其進行加解密,所以就在網上查詢下加解密的相關介紹,最開始採用RSA加解密演算法,先是利用RSAEuro折騰了半天編譯的環節卡住了(編譯報錯查不出原因),後面網上發現利用OpenSSL的實現方法比較簡單。       OpenSSL

Elasticsearch java api 基本搜索部分

ocl 全部 條件 index mod data trace 服務器ip sin 版權聲明:本文非原創文章,轉載出處:http://blog.csdn.net/molong1208/article/details/50512149 一、所使用版本的介紹 使用的是ela

JAVA學習路線圖(一文

-h 基礎 tex 蝸牛 學習路線 jdbc sql https ase 此乃是java攻城獅的學習路線圖,由簡到繁,由易到難,一步步的學習,最後成為JAVA攻城獅。 階段1 1:學習HTML 2:學習CSS 3:JavaScript

Java的內存回收機制

out 結果 int destroy pan 得出 ida public toc http://blog.csdn.net/mengern/article/details/38150431 Java中提供了垃圾強制回收機制的方法System.gc(),但是系統並不保證會立即

Java中的異常和處理

stat 一個 局部變量 lose 出了 object sta tof .html 原文出處:代碼鋼琴家 簡介 程序運行時,發生的不被期望的事件,它阻止了程序按照程序員的預期正常執行,這就是異常。異常發生時,是任程序自生自滅,立刻退出終止,還是輸出錯誤給用戶?或者用C語

windows命令行中java和javac、javap使用(java編譯命令)

路徑 point 目錄 pan static article 字節碼 區別 string 如題,首先我們在桌面,開始->運行->鍵入cmd 回車,進入windows命令行。進入如圖所示的畫面: 可知,當前默認目錄為C盤Users文件夾下的Administr

Java排序方法sort的使用

html i++ val .html adding line 默認 ava int 原文:http://www.cnblogs.com/minshia/p/6283858.html 對數組的排序: 1 2 3 4 5 6 7 8 //對數組排序 pu

jsp 九大內置象和其作用

tex next 應用服務 java 響應 exceptio servle 輸出流 XML JSP中一共預先定義了9個這樣的對象,分別為:request、response、session、application、out、pagecontext、config、page、exc

Java filter中的chain.doFilter

except detail jsp app pub 正常的 如果 舉例 splay 轉載: 一.chain.doFilter作用 1.一般filter都是一個鏈,web.xml 裏面配置了幾個就有幾個。一個一個的連在一起 request -> filter1 -&g

Java 調用 shell 腳本

生產環境 inpu lai home throws next erl 當前 例子 這一年的項目中,有大量的場景需要Java 進程調用 Linux的bash shell 腳本實現相關功能。 從之前的項目中拷貝的相關模塊和網上的例子來看,有個別的“陷阱”造成調用shell 腳本

Java中==和equals和區別+案例

兩個 布爾型 整數 返回 boolean 和equal clas 定義 true 一開始遇見==和equals我也是分不清,後來看了很多博客,收益匪淺, 擔心以後給忘了,所以寫下這個,以後復習可以用。 (有哪裏寫得不對的,希望可以留言幫忙改進,大家一起共同進步) 一、Jav

Java學習筆記54(反射

pos code 重名 java學習筆記 spl catch 兩種 new fig 反射概念: java反射機制是在運行狀態中,對於任意一個類,都能知道所有屬性和方法 對於任意一個對象都能調用它的任意一個方法和屬性,這種動態獲取和調用的功能稱為java的反射機制 實際作