- 代码
去博客设置页面,选择一款你喜欢的代码片高亮样式,下面展示同样高亮的 代码片.
import os
import sys
import chardet
import hashlib
import struct
base_PATH = os.path.abspath('.')
class Md5Encryption(object):
def __init__(self, base_path):
# 项目主路径
self.base_path = base_path
# 收集文件列表
self.files_list = []
# 收集MD5码文件
self.md5_file = self.base_path + '/md5.txt'
# 换行分隔符的模式
self.tp = ''
# 自定义数据
self.custom = None
# 默认忽略的文件和文件夹 这里的文件或文件夹,需要填入相对路径
self.ignore = ['.git', '.idea', 'MD5.py']
def custom_files_or_dirs(self):
"""
自定义生成MD5码的文件
-D: 不生成MD5码的文件夹
-d: 仅生成指定文件夹下文件的MD5码
-F: 不生MD5码的文件
-f: 仅对指定文件生成MD5码
-a: 对所有文件进行处理
-h: 帮助
:return: custom_list
"""
print('开始按照{0}模式收集文件'.format(sys.argv[1]))
if '-D' == sys.argv[1]:
custom_list = sys.argv[2:]
files_list = self.ignore_dirs(self.base_path, custom_list)
elif '-d' == sys.argv[1]:
custom_list = sys.argv[2:]
files_list = self.dispose_dirs(self.base_path, custom_list)
elif '-F' == sys.argv[1]:
custom_list = sys.argv[2:]
files_list = self.dispose_files(self.base_path, custom_list)
print(len(files_list))
elif '-f' == sys.argv[1]:
custom_list = sys.argv[2:]
files_list = self.dispose_files(self.base_path, custom_list)
print(len(files_list))
elif '-a' == sys.argv[1]:
files_list = self.get_all_files(self.base_path)
elif '-h' == sys.argv[1]:
print("""
1. 脚本执行命令: python md5_encryption.py [自定义数据参数类型] [数据]
2. 自定义数据参数类型有: '-D', '-d', '-F'. '-f'
3. 数据之间用空格隔开
4. -D: 不生成MD5码的文件夹
-d: 仅生成指定文件夹下文件的MD5码
-F: 不生MD5码的文件
-f: 仅对指定文件生成MD5码
-a: 对所有文件进行处理
-h: 帮助
""")
sys.exit(0)
else:
raise Exception('自定义数据参数传入异常, 仅支持 "-D", "-d", "-F", "-f" 参数选择')
if not files_list:
raise TypeError('文件收集异常,当前文件收集模式是{0}'.format(sys.argv[1]))
#else:
#lz_logger.info('文件收集成功')
return files_list
def ignore_dirs(self, base_path, custom_list=None):
"""
忽略不生成MD5的文件夹
:param base_path: 路径
:param custom_list: 待处理的文件列表
:return: 收集的文件列表
"""
base_dir_list = self.ignore_default_dir(base_path)
for item in base_dir_list:
src = os.path.join(base_path, item)
if os.path.exists(src):
if item in custom_list:
continue
else:
if os.path.isdir(src):
self.ignore_dirs(src, custom_list)
else:
self.add_files(src)
else:
raise IOError('{}: 当前文件或文件夹不存在!'.format(src))
return self.files_list
def dispose_dirs(self, base_path, custom_list=None):
"""
处理需要生成MD5的文件夹
:param base_path: 路径
:param custom_list: 待处理的文件列表
:return: self.files_list
"""
if base_path != self.base_path:
custom_list = os.listdir(base_path)
custom_list.sort()
for item in custom_list:
src = os.path.join(base_path, item)
if os.path.exists(src):
if os.path.isdir(src):
self.dispose_dirs(src, custom_list)
else:
self.add_files(src)
else:
raise IOError('{}: 当前文件或文件夹不存在!'.format(src))
return self.files_list
def dispose_files(self, base_path, custom_list=None):
"""
处理文件
:param base_path: 文件路径
:param custom_list: 待处理的文件列表
:return: self.files_list
"""
base_dir_list = self.ignore_default_dir(base_path)
for item in base_dir_list:
src = os.path.join(base_path, item)
if os.path.exists(src):
if os.path.isdir(src):
self.dispose_files(src, custom_list)
else:
if sys.argv[1] == '-F':
if item in custom_list:
continue
else:
self.add_files(src)
elif sys.argv[1] == "-f":
if item in custom_list:
self.add_files(src)
else:
continue
else:
raise IOError('{}: 当前文件或文件夹不存在!'.format(src))
return self.files_list
def ignore_default_dir(self, base_path):
"""
处理默认需要忽略掉的文件或文件夹
:param base_path: 路径
:return: base_dir_list
"""
base_dir_list = os.listdir(base_path)
base_dir_abs_path_list = [os.path.join(base_path, path) for path in base_dir_list]
for data in self.ignore:
data_path = self.base_path + data
if data_path in base_dir_abs_path_list:
base_dir_list.remove(os.path.basename(data_path))
base_dir_list.sort()
return base_dir_list
def get_all_files(self, base_path):
"""
获取所有.py或.sh结尾的文件列表 / 获取所有.txt文件
:param base_path: 文件路径
:return: self.files_list
"""
base_dir_list = self.ignore_default_dir(base_path)
for item in base_dir_list:
src = os.path.join(base_path, item) #路径拼接
if os.path.exists(src):
if os.path.isdir(src): #判断某一路径是否为目录
self.get_all_files(src)
else:
self.add_files(src)
else:
raise IOError('{}: 当前文件或文件夹不存在!'.format(src))
return self.files_list
def add_files(self, path):
if os.path.exists(path):
if os.path.isfile(path):
if (os.path.basename(path).endswith('.txt') or os.path.basename(path).endswith('.xlsx') or os.path.basename(path).endswith('.docx'))
and os.path.getsize(path) != 0:
self.files_list.append(path)
else:
raise IOError('{}: 当前文件不存在!'.format(path))
return True
def format_conversion(self, files_list):
"""
用于同一文件的格式, 不同操作系统的换行分割符不同,会导致同一代码的MD5码不同
所以统一项目的换行分割符是 LF
:param files_list:
:return:
"""
if not files_list:
raise TypeError('文件列表为空, 收集文件时异常')
else:
for path in files_list:
file_name = os.path.basename(path)
print('开始格式化: {0}'.format(file_name))
read_data = self.read_file(path)
#print(read_data)
encoding = chardet.detect(read_data)['encoding']
print(encoding)
data_str = read_data.decode('UTF-8', 'ignore').strip().strip(b'x00'.decode())
print('{0}: 文件正常读入'.format(file_name))
if 'rn' in data_str:
self.tp = "CRLF"
data_str = data_str.replace('rn', 'n')
print('将Windows系统的换行分割符CRLF转为Unix and OS X 的 LF')
elif 'r' in data_str:
self.tp = "CR"
data_str = data_str.replace('r', 'n')
print('将Classic Mac系统的换行分割符CRLF转为Unix and OS X 的 LF')
if self.tp == 'CR' or self.tp == 'CRLF':
try:
with open(path, 'w', newline='n', encoding='utf-8') as f:
f.write(data_str)
except IOError:
print('格式化文件{0}写入异常'.format(file_name))
print('格式化文件{0}写入异常'.format(file_name))
print('格式化: {0} 成功'.format(file_name))
print('文件格式统一化完成')
return True
def generate_hash(self, files_list):
"""
用于生成每一个文件对应的MD5码
:param files_list:
:return:
"""
if files_list:
for file_path in files_list:
file = os.path.basename(file_path)
data = self.read_file(file_path)
md5 = hashlib.md5(data).hexdigest() # 生成MD5
md5_data = file + ": " + md5
md5_data = md5_data.encode("utf-8")
self.write_md5_code_to_file(self.md5_file, md5_data)
else:
raise TypeError('files_list is empty! 文件收集异常')
return True
def read_file(self, file_path):
"""
读取文件内容
:param file_path:
:return:
"""
if not os.path.exists(file_path):
raise IOError("读取文件失败! 文件不存在")
else:
try:
if (os.path.basename(file_path).endswith('.txt')):
with open(file_path, 'rb') as f:
data = f.read()
return data
if (os.path.basename(file_path).endswith('.docx')):
with open(file_path, mode = 'rb') as f:
a = f.read()
#print(f"n{a}")
return a
if (os.path.basename(file_path).endswith('.xlsx')):
with open(file_path, mode='rb') as f:
a = f.read()
# print(f"n{a}")
return a
except IOError:
print('文件读取异常')
def write_md5_code_to_file(self, file_path=None, data=None):
"""
写入文件内容
:param file_path:
:param data:
:return:
"""
try:
with open(file_path, 'ab+') as f:
write_data = data + 'n'.encode()
f.write(write_data)
except IOError:
print('文件写入异常')
def check_file(self):
if os.path.exists(self.md5_file):
print('收集MD5码文件已存在')
os.remove(self.md5_file)
print('删除MD5码收集文件')
#else:
# print('收集MD5码文件不存在')
return True
def run(self):
files_list = self.custom_files_or_dirs()
print('检查收集MD5码文件是否存在')
self.check_file()
print('开始统一文件格式')
self.format_conversion(files_list)
print('开始对每个文件生成对应MD5码')
self.generate_hash(files_list)
if __name__ == '__main__':
md5 = Md5Encryption(base_PATH)
md5.run()
参考资料:https://blog.csdn.net/weixin_44252609/article/details/109055018?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522163219179316780271584475%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=163219179316780271584475&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2blogfirst_rank_v2~rank_v29-1-109055018.pc_v2_rank_blog_default&utm_term=MD5&spm=1018.2226.3001.4450



