Python批量修改文件md5

484 阅读3分钟

MD5介绍

MD5的全称是Message-Digest Algorithm 5,它一种被广泛使用的密码散列函数,可以产生出一个128位(16字节)的散列值(hash value),用于确保信息传输完整一致。

MD5值等同于文件的ID,它的值是唯一的。 如果文件已被修改(例如嵌入式病毒,特洛伊木马等),其MD5值将发生变化。 因此,一些常规下载URL提供文件MD并且通常提供MD5值。 如果用户在下载后发现他们的MD5值与网站公告不一致,可能是文件被修改过或者下载出错。

需求

苹果机审是马甲包混淆被打回来的一大障碍,机审一般是比较文件的MD5是否一致,所以我们单单修改文件的名称是不够的,需要我们批量修改工程中图片等文件资源的MD5值。

方案

MD5哈希算法是基于文件内容的,而不考虑文件的元数据,如创建日期、文件名等。只要图片的像素数据没有被修改,无论你修改了哪些元数据,都不会改变其MD5哈希值。

所以,我们需要对文件的内容进行修改。

压缩

我们通过压缩图片生成新的图片。

缺点:当对同一张图片进行压缩时,如果压缩参数相同,生成的图片MD5是一样的,会重复。当再次压缩已经压缩过的图片,可以解决这个问题,但是多次压缩后会造成图片模糊。

添加噪点

我们可以在图片任意四个角,取一点添加一个1px的像素点,像素颜色随机生成。

缺点:图片上的噪点看起来可能会比较明显,显得很突兀,生成相同的噪点也会造成MD5重复。

修改文件二进制值

通过读取文件的二进制值,在末尾添加时间戳作为标记

优点:支持任意文件。多次处理后,图片显示与原图一致,同时MD5不会重复。

完整代码

import hashlib
import os
import re
import time


def get_md5(image_path):
    # 计算处理后的图片的MD5哈希值
    with open(image_path, 'rb') as file:
        md5 = hashlib.md5(file.read()).hexdigest()
        print(f"MD5哈希值: {md5}")


def change_md5_folder(root_folder):
    """
    修改文件中所有文件MD5
    """
    # 递归遍历文件夹及其子文件夹中的所有文件
    for foldername, subfolders, filenames in os.walk(root_folder):
        for filename in filenames:
            # 获取图片文件的完整路径
            image_path = os.path.join(foldername, filename)
            # 调用处理图片的函数
            change_md5_file(image_path)


def change_md5_file(file_path):
    """
    修改文件MD5,在末尾添加时间戳来改变MD5
    """
    # 读取图片二进制数据
    with open(file_path, "rb") as file:
        file_data = file.read()

    # 使用正则表达式匹配以 "TAG" 开头和以数字结尾的模式
    match = re.search(b"TAG\\d+$", file_data)
    timestamp = str(int(time.time())).encode()  # 获取当前时间戳并转换为字节
    if match:
        # 如果匹配到 "TAG" 开头和数字结尾的模式,将数字替换为时间戳
        new_image_data = re.sub(b"KK\\d+$", b"TAG" + timestamp, file_data)
    else:
        # 如果没有匹配到模式,添加 "KK" 时间戳
        new_image_data = file_data + b"TAG" + timestamp

    # 保存新的文件
    output_path = file_path
    with open(output_path, "wb") as output_image_file:
        output_image_file.write(new_image_data)
    print(f"已处理并保存为 {output_path}")


if __name__ == '__main__':
    change_md5_folder('/Users/alen/Aproject/flutter_project/assets')