文件md5加密演算法:文件md5是什麼

最近想做一個文件管理庫,發現文件多到一定程度後只用文件名來管理有些困難,想嘗試下用其它方法來管理文件,這時想起來各類網盤工具中的「秒傳」功能,在傳文件時,幾個G的文件一下就傳上去了,但其實就沒傳,原理據說就是計算文件的md5值,然後檢查系統里已經有這個文件了,就不用在上傳了,給用戶顯示「你的文件已經秒傳成功」。

另外日常使用的git在提交文件時也有類似的操作,但用的不是md5而是sha1,打開「.git/objects/ 」目錄裡面就是sha1演算法生成的文件。

sha1和md5的作用是相同的,但sha1碰撞難度更高,有更好的安全性,但在一般情況下,md5就已經夠用了。

動手開始寫代碼,代碼運行起來後,遇到了第一個困難,”磁碟佔用率太高”,記得以前用機械硬碟時,windows動不動就磁碟佔用率100%,用了各種辦法都沒法解決,以為這是微軟在提示用戶,你的硬碟應該升級了,最後只好升級固態硬碟解決了這個問題,沒想到今天又遇到了這個問題。

我用的是php的md5_file()函數計算文件的md5值,當計算2G以上mp4文件的md5值時cpu 內存都正常,磁碟佔用卻率升到70%以上。於是我更換了編程語言,看是否還有這個問題。

首頁找到了一個python計算文件md5值的封裝,但測試下來也是一樣的問題,磁碟佔用率太高,於是又用上了js,在github找到了spark-md5.js這個庫,在瀏覽器前端計算文件的md5值,發現雖然沒有磁碟佔用率太高的問題,但瀏覽器的內存佔用又太高了。

於是就想能不能不判斷下文件大小,對太大的文件不計算md5了,結合文件大小,最後修改時間,創建時間等因素來做文件的唯一標識(找出文件有多少個副本),這個方法並不好,因為文件的元信息是可以隨意改動的,要造出兩個元信息完全一致的文件並不困難。

經人指點後,感覺還是要用md5才行,但對於太大的文件,可以並不計算整個文件的md5,而是抽取文件部分內容計算hash。因為並不需要文件的全部內容。

對於太大的文件使用:文件大小+內容

抽樣(頭、中、尾或每隔xx位元組抽樣一次哈希),寫了一段php代碼來驗證這一思路,發現可行。測試下來沒有磁碟佔用率太高的情況,也不吃內存,沒有性能問題,

function file_md5_16k($path){
  $size=filesize($path);//取得文件大小
  if($size>16384){//如果文件大於16kb
    $str=$size;
    $str.=file_get_contents($path,null,null,0,4096);#文件頭部4kb
    $str.=file_get_contents($path,null,null,(($size/2)-2048),4096);#文件中部4kb
    $str.=file_get_contents($path,null,null,($size-4096),4096);#文件尾部4kb
    return md5($str);
  }else{ //文件不太,不抽樣,直接計算整個文件的hash
    return md5_file($path);
  }
}

這裡只是測試16kb以上的文件就用了抽樣計算,實際應用中16k的文件太小了,大於16kb的文件太多,中間修改了一些內容很會產生重複。應該設置的更大一些。

md5存在重複可能,在md5基礎上再結合文件類型,文件元信息等就可以對文件做唯一標識,避免文件重複,從而建立文件指紋庫。

當然要實現文件「秒傳」要做的遠遠不止這些,這個只是實現原理演算法。

原創文章,作者:投稿專員,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/226488.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
投稿專員的頭像投稿專員
上一篇 2024-12-09 14:50
下一篇 2024-12-09 14:50

相關推薦

發表回復

登錄後才能評論