def main( ):
import confuse_audio
confuse_audio.run(work_directory)
import confuse_picture
confuse_picture.run(work_directory)
import confuse_meta
confuse_meta.run(work_directory)
import confuse_anim
confuse_anim.run(work_directory)
import confuse_video
confuse_video.run(work_directory)
import confuse_text
confuse_text.run(work_directory)
import confuse_bytes
confuse_bytes.run(work_directory)
# 植入垃圾代码 稀释马甲代码
# domain
if __name__ == "__main__":
work_directory = input('input work directory:\n')
work_directory = work_directory.replace('\\','/')
import unittestutls
howlong_benrunning = unittestutls.get_func_time(func=main,log=False)
input(f'appliction complete: running time {round(howlong_benrunning,2)} seconds')
以二进制的方式读入后覆盖源文件
from os.path import isfile
class confuse_base( ):
def __init__(self, filepath:str) -> None:
if not isfile(filepath):
raise ValueError(f"not a file type: {filepath}")
self.filepath = filepath
def confuse( self ):
with open( self.filepath,'rb+') as fp:
content = fp.read()
fp.seek(0)
fp.write(content)
使用PIL修改像素矩阵 确保图片像素变动的同时 表现上无明显差异
from findutils import find_img_files
def run(pro_dir:str):
pro_dir = pro_dir.replace('\\','/')
img_urls = find_img_files( pro_dir )
num_imgs = len(img_urls)
if num_imgs == 0:
print(f'not found image in directory: {pro_dir}')
return
from imgfileutils import auto_modify_img_pixels
import time
s = time.time()
executor = None
# 使用进程池
if num_imgs >= 1e+5:
import concurrent.futures
executor = concurrent.futures.ProcessPoolExecutor()
# 使用线程池
elif num_imgs >= 1e+3:
import concurrent.futures
executor = concurrent.futures.ThreadPoolExecutor()
if executor != None:
# 提交图像处理任务
futures = [executor.submit(auto_modify_img_pixels, arg) for arg in img_urls]
# 等待所有任务完成
concurrent.futures.wait(futures)
else:
#使用协程池
import gevent
from gevent import monkey; monkey.patch_all()
tasks = [gevent.spawn(auto_modify_img_pixels, arg) for arg in img_urls]
gevent.joinall(tasks)
e = time.time()
print(f'处理图片完毕: ({len(img_urls)})|{round(e-s,2)}s')
from PIL import Image,ImageFile
import numpy as np
import random
import os
ImageFile.LOAD_TRUNCATED_IMAGES = True
# 支持的图像文件头信息
supported_headers = {
b'\xFF\xD8\xFF': 'JPEG',
b'\x89\x50\x4E\x47\x0D\x0A\x1A\x0A': 'PNG',
b'\x42\x4D\xe6\x04\x00\x00\x00\x00\x00\x00\x36\x00\x00\x00':'BMP',
b'II*\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00':'TIFF'
# 添加其他支持的图像格式的文件头信息
}
def is_valid_image_bytes(image_bytes):
if len(image_bytes) == 0:
return False
for header, format in supported_headers.items():
if image_bytes.startswith(header):
return True
return False
def modify_pixel(image_path, output_path, x, y, color):
if not os.path.isfile( image_path ):
print(f'{image_path} not a file')
return
if not is_valid_image_bytes(open(image_path,'rb').read()):
print(f'{image_path} is invalid image')
return
# 打开图像
image = Image.open(image_path)
# 将图像转换为 NumPy 数组
img_array = np.array(image)
# 修改指定位置的像素
img_array[y, x] = color # 这里注意纵坐标在前,横坐标在后
# 将 NumPy 数组转换回图像
modified_image = Image.fromarray(img_array)
# 保存修改后的图像
modified_image.save(output_path)
def auto_modify_img_pixels( img_url:str ):
if not os.path.isfile( img_url ):
print(f'无效文件: {img_url}')
return
if not is_valid_image_bytes(open(img_url,'rb').read()):
print(f'无效图片: {img_url}')
return
img = Image.open(img_url)
img = np.asarray(img).copy()
dest = random.randint(0,255-2)
img[img==dest] =dest+1
img = Image.fromarray(img)
img.save(img_url)
print(f'混淆完毕: {img_url}')
# try:
# img = Image.open(img_url)
# img = np.asarray(img).copy()
# dest = random.randint(0,255-2)
# img[img==dest] =dest+1
# img = Image.fromarray(img)
# img.save(img_url)
# except Exception as e:
# print(img_url)
# print(e)
# from unittestutls import get_func_time
# get_func_time( auto_modify_img_pixels,"4.jpg")
使用ffmpeg来进行抽帧
import os
import subprocess
import re
ffmpeg = 'bin/ffmpeg.exe'
cwd = os.getcwd()
def get_audio_duration(file_path):
# 构建 FFmpeg 命令
command = [
ffmpeg,
"-i", file_path,
]
# 执行命令并捕获输出
result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
# 从输出中提取时长信息
duration_match = re.search(r"Duration: (\d{2}:\d{2}:\d{2}\.\d+)", result.stderr)
if duration_match:
duration_str = duration_match.group(1)
# 将时长字符串转换为秒
hours, minutes, seconds = map(float, duration_str.split(":"))
duration_in_seconds = hours * 3600 + minutes * 60 + seconds
return duration_in_seconds
else:
print("Failed to extract duration information.")
return 0
def set_audio_speed( file:str, speed:float ):
cmd = f'{ffmpeg} -y -i {file} -filter_complex "[0:a]atempo={speed}[out]" -map "[out]" {file}'
subprocess.run(cmd)
def set_audio_volume( inputfile:str, volume:float,outfile:str ):
cmd = f'{ffmpeg} -y -i {inputfile} -af "volume={volume}" {outfile}'
subprocess.run(cmd)
cache_audio_path = {}
def proc_one( file_path:str ):
if file_path not in cache_audio_path.keys():
return
set_audio_volume(file_path,1.01,cache_audio_path[file_path])
print(f'修改: {file_path} -> {cache_audio_path[file_path]}')
def proc_all( files:list[str]):
if not os.path.exists('bin/.temp'):
os.mkdir('bin/.temp')
cache_audio_path.clear()
import shutil
for file in files:
tempath = os.path.join( cwd , 'bin\\.temp\\' + file.replace('\\','_').replace('/','_').replace(':','@') )
shutil.move(file,tempath)
cache_audio_path[tempath] = file
print(f'暂存: {file} -> {tempath}')
import time
s = time.time()
import gevent
from gevent import monkey; monkey.patch_all()
tasks = [gevent.spawn(proc_one, arg) for arg in cache_audio_path.keys()]
gevent.joinall(tasks)
e = time.time()
print(f'处理音效完成: {len(files)}|{round(e-s,2)}s')
def run( root_dir: str ):
from findutils import find_audio_files
proc_all( find_audio_files(root_dir) )
from confusebase import confuse_base
import os,shutil,subprocess
cwd = os.getcwd()
ffmpeg = 'bin/ffmpeg.exe'
def delete_frame(input_file, output_file):
# 构建 FFmpeg 命令
command = [
ffmpeg,
'-i', input_file,
'-vf', "select='not(eq(n,1))'",
'-c:v', 'libx264',
'-c:a', 'aac',
'-strict', 'experimental',
output_file
]
# 调用命令
subprocess.run(command)
class confuse_video( confuse_base ):
def __init__(self, filepath: str) -> None:
super().__init__(filepath)
self.temppath = os.path.join( cwd , 'bin\\.temp\\' + filepath.replace('\\','_').replace('/','_').replace(':','@') )
shutil.move(filepath,self.temppath)
def confuse( self ):
delete_frame(self.temppath,self.filepath)
def proc_one( confuse_cls:confuse_base )->None:
confuse_cls.confuse()
def run( root_dir ):
from findutils import find_files
confuse_meta_clss =[ confuse_video(f) for f in find_files(root_dir,'.mp4') ]
import concurrentutils
def foo():
concurrentutils.run(proc_one,*confuse_meta_clss)
from unittestutls import get_func_time
running_time = get_func_time(foo,log=False)
print(f'处理视频完毕: ({len(confuse_meta_clss)})|{running_time}s')
‘.txt’,‘.json’,‘.unity’,‘.prefab’ 这类做文本处理 当然你也可以加些其它的筛选
from confusebase import confuse_base
class confuse_text(confuse_base):
def confuse(self):
with open( self.filepath,'r+') as fp:
fp.seek(0,2)
fp.write("\n")
def proc_one( confuse_cls:confuse_base )->None:
confuse_cls.confuse()
def run( root_dir ):
from findutils import find_files
confuse_meta_clss =[ confuse_text(f) for f in find_files(root_dir,['.txt','.json','.unity','.prefab']) ]
import concurrentutils
def foo():
concurrentutils.run(proc_one,*confuse_meta_clss)
from unittestutls import get_func_time
running_time = get_func_time(foo,log=False)
print(f'处理meta完成: {len(confuse_meta_clss)}|{running_time}s')
from confusebase import confuse_base
def proc_one( confuse_cls:confuse_base )->None:
confuse_cls.confuse()
def run( root_dir ):
from findutils import find_files
confuse_meta_clss =[ confuse_base(f) for f in find_files(root_dir,['.bytes','.fbx','.TTF','.ttf','.asset','.mat','.shader']) ]
import concurrentutils
def foo():
concurrentutils.run(proc_one,*confuse_meta_clss)
from unittestutls import get_func_time
running_time = get_func_time(foo,log=False)
print(f'处理meta完成: {len(confuse_meta_clss)}|{running_time}s')
def run( func, *args):
executor = None
num_reqs = len(args)
# 使用进程池
if num_reqs >= 2e+3+48:
import concurrent.futures
executor = concurrent.futures.ProcessPoolExecutor()
# 使用线程池
elif num_reqs >= 1e+3+24:
import concurrent.futures
executor = concurrent.futures.ThreadPoolExecutor()
if executor != None:
# 提交图像处理任务
futures = [executor.submit(func, arg) for arg in args]
# 等待所有任务完成
concurrent.futures.wait(futures)
else:
#使用协程池
import gevent
from gevent import monkey; monkey.patch_all()
tasks = [gevent.spawn(func, arg) for arg in args]
gevent.joinall(tasks)
def get_func_time( func,*args,log = True ):
import time
s = time.time()
func(*args)
e = time.time()
elapsedTime = round(e-s,2)
if log:
print(f'elapsed time: {elapsedTime}s')
return elapsedTime