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))
