python检测文件的MD5值

MD5(单向散列算法)的全称是Message-Digest Algorithm 5(信息-摘要算法),经MD2、MD3和MD4发展而来。MD5算法的使用不需要支付任何版权费用。      

      每个文件都会有一个MD5的加密值,这个值来唯一标识这个文件,它常用来辨别文件的真伪,例如下载系统安装镜像,旁边会附带一个长长的字符乱码,这就是这个镜像的MD5值。文件被修改后其MD5值也会改变,所以可以用来判断一个文件是否被修改过。这样的方法比基于时间、文件大小的比较显然更加可靠。

感谢大神之作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#!/usr/bin/env python
#coding: utf-8
import 
re
import 
os
import 
shutil
import 
time
import 
random
import 
sys
import 
urllib
import 
hashlib
#重复邮件的目录
FROM_FOLDER_LIST
=
[
"/data/zhangsan/cur"
,]
#准确的,即去重后的需要的邮件
TARGET_FOLDER
=
"/root/patch1"
#得到的重复邮件
TARGET_FOLDER2
=
"/root/patch3"
def 
get_md5_value(src):
        
#调用hashlib里的md5()生成一个md5 hash对象
        
myMd5 
= 
hashlib.md5()
        
#生成hash对象后,就可以用update方法对字符串进行md5加密的更新处理
        
myMd5.update(src)
        
#加密后的十六进制结果
        
myMd5_Digest 
= 
myMd5.hexdigest()
        
#返回十六进制结果
        
return 
myMd5_Digest
MD5_POOL
=
{
}
for 
FROM_FOLDER 
in 
FROM_FOLDER_LIST:
        
for 
root, dirs, files 
in 
os.walk(FROM_FOLDER):
                
for 
file_name 
in 
files:
                        
filepath 
= 
"%s/%s"
%
(root,file_name)
                        
print 
"扫描文件  "
,filepath
                        
#以上几行是循环扫描每个文件,并打印出来
                        
try
:
                                
#打开一个文件,并定义为fobj别名
                                
with 
open
(filepath,
"rb"
) as fobj:
                                        
#读文件
                                        
code 
= 
fobj.read()
                                
#调用获取md5值的函数,返回文件的十六进制结果,并赋值给md5_v变量
                                
md5_v 
= 
get_md5_value(code)
                                
#假如md5_v没在MD5_POOL池(字典)中,然后打印出来,并移动到TARGET_FOLDER目录
                                
if 
not 
md5_v 
in 
MD5_POOL:
                                        
print 
"移动文件 %s 到目录 %s下"
%
(filepath,TARGET_FOLDER)
                                        
shutil.move(filepath, 
"%s/%s"
%
(TARGET_FOLDER,file_name))
                                        
#然后加到池中,一个是key,一个是值
                                        
MD5_POOL[md5_v] 
= 
file_name
                                
else
:
                                        
#假如池中,就重复了,就移动到TARGET_FOLDER2目录
                                        
print 
"%s 是重复文件, 移动到目录 %s下"
%
(filepath,TARGET_FOLDER2)
                                        
shutil.move(filepath, 
"%s/%s"
%
(TARGET_FOLDER2,file_name))
                        
except 
Exception,err:
                                
print 
err
                                
print 
"copy file %s error"
%
filepath
                                
continue