# -*- coding: UTF-8 -*- import os,sys import random import string import re import time import json import shutil import hashlib import time import argparse #该脚本目前只针对Assets.xcassets目录下的文件进行副本、添加; #即:在该脚本执行完毕之后,请将指定的--target 对应目录下的Assets.xcassets拷贝回工程项目替换原有的Assets.xcassets即可 #该脚本会修改原来的png图片的sha值,以及随机添加一些无效的且无法预览fake图片 script_path = os.path.split(os.path.realpath(sys.argv[0]))[0] resource_path = "" target_path = os.path.join(script_path, "target_resource") #匹配规则,路径包含path_include且不包含path_exclude的才会创建对应类型的文件 os.path.sep:代表路径分隔符,即 / match_rule = { ".png": { # "path_include": os.path.sep + "res", }, } #确保添加的函数不重名 funcname_set = set() #单词列表,用以随机名称 with open(os.path.join(script_path, "./ClassName_list.json"), "r") as fileObj: word_name_list = json.load(fileObj) #获取一个随机名称 def getOneName(): global word_name_list return random.choice(word_name_list) #获取png内容 def getPngText(): hexbyte = "0000000049454e44aecd6ab2" text = str(random.randint(1, 100)) * random.randint(1024, 10240) text = text + bytes.fromhex(hexbyte).hex() text = text.encode('utf-8') return text #添加单个文件 def addSingleFile(file_path): global target_path print ("add file " + file_path.replace(target_path, "")) _, file_type = os.path.splitext(file_path) if file_type == ".png": # print("发现png文件,准备在文件末尾追加hex文件操作...") with open(file_path, "wb") as fileObj: fileObj.write(getPngText()) fileObj.close() def addFileTo(parent_folder, level, min_file_num=0): global match_rule, target_path create_folder_list = [] for parent, folders, files in os.walk(parent_folder): target_file_type = "" relative_path = parent.replace(target_path, "") print("relative_path:"+relative_path) for file_type, match_config in match_rule.items(): # print("file_type:" + file_type) print("match_config:" + str(match_config)) if "path_exclude" in match_config and relative_path.find(match_config["path_exclude"]) != -1: continue if "path_include" not in match_config or relative_path.find(match_config["path_include"]) != -1: target_file_type = file_type # print("target_file_type:"+target_file_type) break if not target_file_type: print("不在执行后续的addSingleFile步骤") continue # Create file count 创建 指定的最小文件数量 + 文件列表长度一半 到 文件列表长度 之间 的数量 new_file_num = random.randint(len(files) // 2, len(files)) + min_file_num for i in range(new_file_num): #根据随机的文件名 + 文件后缀类型 拼接为要创建的文件路径 file_path = os.path.join(parent, getOneName() + target_file_type) addSingleFile(file_path) print("已经执行addSingleFile步骤...") # Prevent creating too many levels 如果该目录下已经被自动创建目录,则不再继续自动创建 if level > 2: continue # Create folder count new_fold_num = random.randint(len(folders) // 2, len(folders)) for i in range(new_fold_num): target_folder = os.path.join(parent, getOneName()) # Defer folder creation to avoid interrupting os.walk create_folder_list.append(target_folder) for folder_path in create_folder_list: try: print("create folder", folder_path.replace(target_path, "")) os.makedirs(folder_path, exist_ok=True) # Handle existing folders addFileTo(folder_path, level + 1, random.randint(2, 5)) except Exception as e: print(e) #----------------------------------------ended add file---------------------- def changeSingleFileMD5(file_path): pre_hash_valaue = calculate_sha256_hash(file_path) # print("pre_hash_value:\n" + pre_hash_valaue) _, file_type = os.path.splitext(file_path) with open(file_path, "ab") as fileObj: if file_type == ".png": text = "".join(random.sample(string.ascii_letters, 11)) elif file_type == ".jpg": text = "".join(random.sample(string.ascii_letters, 20)) else: text = " "*random.randint(1, 100) fileObj.write(text.encode('utf-8')) fileObj.close() after_hash_valaue = calculate_sha256_hash(file_path) # print("after_hash_valaue:\n" + after_hash_valaue) #改变文件md5 def changeFolderMD5(target_path): # type_filter = set([".png", ".jpg", ".json", ".plist", ".fnt"]) #暂时不处理json、pilist文件 type_filter = set([".png", ".jpg"]) for parent, folders, files in os.walk(target_path): for file in files: full_path = os.path.join(parent, file) _, file_type = os.path.splitext(full_path) if file_type in type_filter: changeSingleFileMD5(full_path) #返回文件的hash值 def calculate_sha256_hash(file_path): with open(file_path, 'rb') as f: data = f.read() hasher = hashlib.sha256() hasher.update(data) return hasher.hexdigest() #----------------------------------------------------main------------------------------------------------ def parse_args(): global res_path parser = argparse.ArgumentParser(description='资源变异工具') parser.add_argument('--res', dest='res_dir', type=str, required=True, help='资源目录') parser.add_argument('--target', dest='target_dir', type=str, required=False, default=target_path, help='资源导出目录') args = parser.parse_args() return args def main(): global resource_path, target_path app_args = parse_args() resource_path = app_args.res_dir target_path = app_args.target_dir if not os.path.exists(resource_path): print ("res path not exists: " + resource_path) exit(0) if target_path != resource_path: if os.path.exists(target_path): shutil.rmtree(target_path) shutil.copytree(resource_path, target_path) #执行png文件的添加、目录的创建 addFileTo(target_path, 0) print ("\n\nstart modify file md5") changeFolderMD5(target_path) print ("finish!") if __name__ == "__main__": main()