如何使用Java計算修改文件的MD5值
什么是 MD5 ?
MD5(Message Digest Algorithm,信息摘要算法),一種被廣泛使用的密碼散列函數(shù),可以產(chǎn)生出一個128位(16字節(jié))的散列值(hash value),用于確保信息傳輸完整一致。它后面這個數(shù)字 5 是因為它是為了取代 MD4 而發(fā)明的。簡單的理解,它的作用就是給文件一個唯一標識。 如果我們修改了一個文件的擴展名,文件可能會打不開,但是對于 MD5 來說,并沒有什么改變。所以對于一個文件,進行任何的重新命名對于md5校驗都是沒有用的。
MD5 的應用
這里只提幾點我見過的比較頻繁的應用情況。
下載文件校驗
因為網(wǎng)絡并不是完美的,下載大文件的過程中可能會出錯(小文件也會,但是通常越大的文件幾率越大),這是很正常的現(xiàn)象,網(wǎng)絡出現(xiàn)波動是很正常的。所以,通常有些軟件的jar或開發(fā)工具會額外提供一個文件的md5值下載(因為它很小,通常認為是不會出錯的),用于用戶校驗文件是否下載錯誤。但是現(xiàn)在網(wǎng)絡也是越來越好了,基本上不會錯誤。(所以我沒有使用過,如果用戶的網(wǎng)絡環(huán)境不是很好,下載完畢一定要校驗一下,免得出錯。)
上傳文件
相比之下,md5值上傳文件的應用范圍就更大了。這里主要的用途是為了文件去重和文件過濾。
文件去重
我們知道用戶上傳的文件中,一般都是有很多重復的,如最近流行的電影、電視劇、游戲或者其它的流行資源。其實它們占據(jù)了用戶上傳文件的很大一部分,所以對于同一份資源,只需要存儲一份就可以了。試想一下,一萬個用戶(一萬可能都少了)上傳了同一份 4GB 的電影,那么總共需要磁盤容量:4*10000 GB。如果只是上傳一份,對于其它用戶的上傳只是在本地計算文件的 md5值 ,如果相同就認為是同一個文件,那么就只需要 4GB 空間就足夠了(當然,這里忽略了記錄信息的空間大小,但是相比于文件本身的大小,這些信息還是很小的)。大家可以想一下,這樣對于空間的節(jié)約是多么巨大的。
大家生活中,應該經(jīng)常用到,上傳一個幾個 GB 的大文件,居然幾秒鐘就完成了,但是稍微有點網(wǎng)絡知識的都知道,網(wǎng)絡的上傳速率是小于下載速率的(這只是對于終端用戶來說),下載都達不到的速度,上傳更是不可能的。所以,它應該只是進行了一個文件md5值的計算過程,根據(jù)計算的結果,如果有就不上傳,只是記錄一下用戶擁有這個文件而已。如果沒有的話,就老老實實上傳,當然了,這個過程通常很慢。
文件過濾
有一些文件涉及到版權和政策的關系,是不允許用戶上傳的。所以,對于用戶上傳文件也會進行校驗,然后和后臺的黑名單匹配(應該是這樣的),如果匹配成功的話,那么文件是無法上傳或者上傳的文件已經(jīng)被處理掉了。這樣方法的效率很高的,通常用戶所謂的亂改名操作是完全沒有用的。所以,用戶一定要遵守政策和相關平臺的規(guī)定。
修改文件的 MD5 值
一般情況下,只要改變了文件的二進制內容,文件的md5值一定會改變的。通常有利用壓縮文件的方式,將多個文件壓縮上傳的方式,這樣壓縮文件的 md5值也會改變,但是有的平臺也是可以解壓文件的,所以這樣也不是萬能的。但是通過程序修改和還原文件的二進制數(shù)據(jù)還是比較容易地,使用Java的流幾乎可以對與文件進行任何操作(例如對于文件的每個字節(jié)進行加密,這樣想還原這個文件就是很難的,或者只是加密一段或者首先創(chuàng)建一個文件,先向文件寫入一段固定的數(shù)字,再寫入相關文件的數(shù)據(jù),這樣也是很不錯的方法。)。對于文件來說,我們可以簡單地把它看出是一連串連續(xù)地二進制流(邏輯上),將它合并(增加)或者截斷(減少)是很簡單地操作,這里就是簡單的涉及文件 和 IO流的知識了。
我上次寫了一個關于文件合并操作的程序,可以將文本、圖片和視頻進行合并,如果感興趣,可以參考一下:文件合并(圖片+視頻),修改md5值,隱藏文件
一個簡單的計算 md5 的程序
這個程序是Java網(wǎng)絡編程上面的,這里去掉了線程,簡化了一下操作,反正只是用于計算md5值,不需要用戶的其它操作。
import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.security.DigestInputStream; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import javax.xml.bind.DatatypeConverter; public class TestMD5 { public static void main(String[] args){ for (String filepath : args) { String md5 = computeMD5(new File(filepath)); System.out.println(md5); } } private static String computeMD5(File file) { DigestInputStream din = null; try { MessageDigest md5 = MessageDigest.getInstance("MD5"); //第一個參數(shù)是一個輸入流 din = new DigestInputStream(new BufferedInputStream(new FileInputStream(file)), md5); byte[] b = new byte[1024]; while (din.read(b) != -1); byte[] digest = md5.digest(); StringBuilder result = new StringBuilder(file.getName()); result.append(": "); result.append(DatatypeConverter.printHexBinary(digest)); return result.toString(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { if (din != null) { din.close(); } } catch (IOException e) { e.printStackTrace(); } } return null; } }
運行結果
修改 MD5 值
這里有兩個圖片,對它們進行合并,注意我這里的合并,不是通常所說的文件合并(例如合成九宮格圖片),而是將文件的二進制數(shù)據(jù)合并。
先計算文件的 md5 值,注意下面的 Ahusky.jpeg 是上面的 husky.jpeg 的重命名,可以看出來對于md5值來說并沒有變化,所以這是同一個文件。
然后將文件合并,這里用到的程序是我上面關于文件合并里面介紹的??梢赃M入了解詳情,這里不再介紹了。
計算合并后文件的 md5 值
到此這篇關于如何使用Java計算修改文件的MD5值的文章就介紹到這了,更多相關Java計算修改文件的MD5值內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
java 實現(xiàn)下壓棧的操作(能動態(tài)調整數(shù)組大小)
這篇文章主要介紹了java 實現(xiàn)下壓棧的操作(能動態(tài)調整數(shù)組大小),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-02-02Java數(shù)組高級算法與Arrays類常見操作小結【排序、查找】
這篇文章主要介紹了Java數(shù)組高級算法與Arrays類常見操作,結合實例形式總結分析了Java數(shù)組常見的排序算法、查找算法相關原理、實現(xiàn)與使用技巧,需要的朋友可以參考下2019-03-03詳解如何在SpringBoot項目中使用統(tǒng)一返回結果
在一個完整的項目中,如果每一個控制器的方法都返回不同的結果,那么對項目的維護和擴展都會很麻煩。因此,本文為大家準備了SpringBoot項目中使用統(tǒng)一返回結果的方法,需要的可以參考一下2022-10-10SpringBoot實現(xiàn)阿里云快遞物流查詢的示例代碼
本文將基于springboot實現(xiàn)快遞物流查詢,物流信息的獲取通過阿里云第三方實現(xiàn),具有一定的參考價值,感興趣的可以了解一下2021-10-10spring mvc中的@PathVariable獲得請求url中的動態(tài)參數(shù)
本文主要介紹了spring mvc中的@PathVariable獲得請求url中的動態(tài)參數(shù)的代碼。具有很好的參考價值,下面跟著小編一起來看下吧2017-02-02