0.起因
公司安排任务:私服的一致性鉴定
需要对比私服文件和官方文件所有文件的文件名和内容的一致性和相似性
1.走过的弯路
最初只从对比文件名是否相同出发,然后找出所有文件名相同且哈希值相同的文件.
存在的问题:安装包内存在很多同名且同哈希的文件,会重复计算很多次,比如名字是1.uib的文件就有8个,如果直接判断就会找出,1个文件同8个文件重复,这不是我想要达到的效果
2.最后的结果
通过判断是否在列表内,在通过索引反查找
代码如下:
import os
# 导入工作簿
import openpyxl
# 哈希值
import hashlib
def get_Filelist(dir, Filelist):
'''
:param dir: 文件夹的路径,形如:E:\\software\\Notepad++
:param Filelist:列表,形如:[]
:return:返回该文件夹下所有文件的路径
'''
newDir = dir
if os.path.isfile(dir):
Filelist.append(dir)
# # 若只是要返回文件文,使用这个
# Filelist.append(os.path.basename(dir))
elif os.path.isdir(dir):
for s in os.listdir(dir):
# 如果需要忽略某些文件夹,使用以下代码
# if s == "xxx":
# continue
newDir = os.path.join(dir, s)
get_Filelist(newDir, Filelist)
return Filelist
def name_hash_list(fake_file_list, real_file_list):
'''
:param fake_file_list:私服文件路径
:param real_file_list:官服文件路径
:return:私服和官服哈希文件列表
'''
fake_hash_list = []
real_hash_list = []
fake_name_list = []
real_name_list = []
for i in fake_file_list:
with open(i, "rb") as f:
bytes = f.read() # read file as bytes
fake_hash = hashlib.md5(bytes).hexdigest()
fake_hash_list.append(fake_hash)
# 不区分大小写
fake_name_list.append(os.path.split(i)[-1].upper())
for i in real_file_list:
with open(i, "rb") as f:
bytes = f.read() # read file as bytes
real_hash = hashlib.md5(bytes).hexdigest()
real_hash_list.append(real_hash)
# 不区分大小写
real_name_list.append(os.path.split(i)[-1].upper())
return fake_hash_list, fake_name_list, real_hash_list, real_name_list
def select_name_hash(fake_hash_list, fake_name_list, real_hash_list, real_name_list):
# 同名且同哈希
result_list_1 = []
# 同名不同哈希
result_list_2 = []
# 不同名同哈希
result_list_3 = []
# 不同名不同哈希
result_list_4 = []
for i in range(len(fake_hash_list)):
if fake_name_list[i] in real_name_list and fake_hash_list[i] in real_hash_list:
real_name = fake_name_list[i]
real_hash = fake_hash_list[i]
result_list_1.append([fake_name_list[i], real_name, fake_hash_list[i], real_hash])
elif fake_name_list[i] in real_name_list and fake_hash_list[i] not in real_hash_list:
real_name = fake_name_list[i]
real_hash = real_hash_list[real_name_list.index(real_name)]
result_list_2.append([fake_name_list[i], real_name, fake_hash_list[i], real_hash])
elif fake_name_list[i] not in real_name_list and fake_hash_list[i] in real_hash_list:
real_hash = fake_hash_list[i]
# 存在不同名,但是同时有很多重复的情况
real_name = real_name_list[real_hash_list.index(real_hash)]
result_list_3.append([fake_name_list[i], real_name, fake_hash_list[i], real_hash])
else:
result_list_4.append([fake_name_list[i], 0, fake_hash_list[i], 0])
return result_list_1, result_list_2, result_list_3, result_list_4
def write_xlsx(dir, name):
# 初始化表格1
wb = openpyxl.Workbook()
ws = wb.active
# 表名
ws.title = name
id = 1
for i in range(1, len(dir) + 1):
ws.cell(row=i, column=1, value=id)
ws.cell(row=i, column=2, value=dir[i - 1][0])
ws.cell(row=i, column=3, value=dir[i - 1][1])
ws.cell(row=i, column=4, value=dir[i - 1][2])
ws.cell(row=i, column=5, value=dir[i - 1][3])
id += 1
wb.save(str(name) + '.xlsx')
if __name__ == '__main__':
# 私服文件夹路径
fake_file_name = 'F:\\火龙服务器文件\\热血传奇\\wav'
# 官服文件夹路径
real_file_name = 'E:\\doc\\Legend of mir\\wav'
# 1. 找出该文件夹下所有文件路径
fake_file_list = get_Filelist(fake_file_name, [])
real_file_list = get_Filelist(real_file_name, [])
print(len(fake_file_list), len(real_file_list))
# 2.找出路径对应的文件名列表和哈希列表
fake_hash_list, fake_name_list, real_hash_list, real_name_list = name_hash_list(fake_file_list, real_file_list)
# print(len(fake_hash_list))
# 3.判断名字和哈希是否相同情况(可以使用文件名和哈希是否在官服的列表里)
result_list_1, result_list_2, result_list_3, result_list_4 = select_name_hash(fake_hash_list, fake_name_list,
real_hash_list, real_name_list)
# 4.写入表格
if len(result_list_1) > 0:
write_xlsx(result_list_1, "同名同哈希")
else:
print("不存在同名同哈希的文件")
if len(result_list_2) > 0:
write_xlsx(result_list_2, "同名不同哈希")
else:
print("不存在同名不同哈希的文件")
if len(result_list_3) > 0:
write_xlsx(result_list_3, "不同名同哈希")
else:
print("不存在不同名同哈希的文件")
if len(result_list_4) > 0:
write_xlsx(result_list_4, "不同名不同哈希")
else:
print("不存在不同名不同哈希的文件")
# 5.总数统计
result_1 = len(result_list_1) / len(fake_hash_list)
result_2 = len(result_list_2) / len(fake_hash_list)
result_3 = len(result_list_3) / len(fake_hash_list)
result_4 = len(result_list_4) / len(fake_hash_list)
print("总文件数:{},同名同哈希数:{},占比数:{:.2%}".format(len(fake_hash_list), len(result_list_1), result_1))
print("总文件数:{},同名不同哈希数:{},占比数:{:.2%}".format(len(fake_hash_list), len(result_list_2), result_2))
print("总文件数:{},不同名同哈希数:{},占比数:{:.2%}".format(len(fake_hash_list), len(result_list_3), result_3))
print("总文件数:{},不同名不同哈希数:{},占比数:{:.2%}".format(len(fake_hash_list), len(result_list_4), result_4))