侧边栏壁纸
博主头像
YOUZI

我依旧在追寻自由的路上

  • 累计撰写 85 篇文章
  • 累计创建 10 个分类
  • 累计创建 27 个标签

目 录CONTENT

文章目录

随机重命名后保证MD图片插入顺序正常

柚子
原创 / 2024-08-06 / 0 评论 / 1 点赞 / 26 阅读 / 0 字
温馨提示:
本文最后更新于43天前,若内容或图片失效,请留言反馈。 部分素材来自网络,若不小心影响您的利益,请联系 站长 删除。

思路

整个过程不进行文件处理,如压缩、格式转换,避免哈希值发生变化,所以建议该流程处于末尾。

流程图

flowchart LR 记录初始哈希值:A --> 记录重命名后哈希值:B --> 按A将B重新排列:C

代码

哈希记录

import os
import hashlib
import json
import re


def natural_sort_key(s):
    """
    用于自然排序的键函数。
    
    自然排序意味着像“1”, “2”, “10”这样的字符串会按照数值的顺序排序,而不是字典顺序。
    """
    # 分割字符串,将数字和非数字部分分开,以便于排序
    return [int(text) if text.isdigit() else text.lower() for text in re.split('(\d+)', s)]


def calculate_file_hash(file_path, hash_algo='md5'):
    """
    计算文件的哈希值,支持多种哈希算法。
    
    :param file_path: 文件的路径
    :param hash_algo: 使用的哈希算法,默认为md5
    :return: 文件的哈希值字符串,如果计算出错则返回None
    """
    hash_func = hashlib.new(hash_algo)
    try:
        # 以二进制模式打开文件,逐块读取并更新哈希值
        with open(file_path, 'rb') as file:
            while chunk := file.read(8192):
                hash_func.update(chunk)
    except Exception as e:
        # 如果在读取文件或计算哈希时出错,打印错误信息并返回None
        print(f"计算文件哈希时出错: {file_path} - {e}")
        return None
    # 返回最终的哈希值,作为字符串
    return hash_func.hexdigest()


def load_existing_hashes(json_output_path):
    """
    从JSON文件中加载现有的哈希值。
    
    :param json_output_path: 存储哈希值的JSON文件路径
    :return: 现有哈希值的字典,如果文件不存在或不是有效的JSON格式,则返回空字典
    """
    if os.path.exists(json_output_path):
        with open(json_output_path, 'r') as json_file:
            try:
                # 尝试从文件中加载哈希值字典
                return json.load(json_file)
            except json.JSONDecodeError:
                # 如果文件不是有效的JSON格式,返回空字典
                return {}
    return {}


def calculate_hash(folder_path, json_output_path, merge=False, sort_mode='alphabetical', hash_algo='md5'):
    """
    计算指定文件夹中所有文件的哈希值,并将结果保存到JSON文件中。
    
    :param folder_path: 包含待计算哈希值文件的文件夹路径
    :param json_output_path: 用于保存哈希值的JSON文件路径
    :param merge: 如果为True,则将新的哈希值合并到现有的哈希值字典中,否则创建新的字典
    :param sort_mode: 排序模式,可以是'alphabetical'(字典顺序)或'natural'(自然排序)
    :param hash_algo: 使用的哈希算法,默认为md5
    """
    # 列出文件夹中的所有文件名
    filenames = os.listdir(folder_path)

    # 根据用户选择进行排序
    if sort_mode == 'natural':
        filenames.sort(key=natural_sort_key)
    elif sort_mode == 'alphabetical':
        filenames.sort()
    else:
        # 如果sort_mode不是已知的合法值,抛出错误
        raise ValueError("无效sort_mode,请选择“natural”或“alphabetical”。")

    # 加载现有哈希值
    file_hashes = load_existing_hashes(json_output_path) if merge else {}

    # 遍历文件夹中的每个文件
    for filename in filenames:
        file_path = os.path.join(folder_path, filename)

        if os.path.isfile(file_path):
            # 计算文件的哈希值
            file_hash = calculate_file_hash(file_path, hash_algo)
            if file_hash is not None:  # 只有在哈希计算成功时才更新字典
                file_hashes[filename] = file_hash

    # 将更新后的文件哈希值字典保存到JSON文件中
    with open(json_output_path, 'w') as json_file:
        json.dump(file_hashes, json_file, indent=4)
    print(f"哈希值已保存到:{json_output_path}")

哈希排序

import json


def hash_sorting(a_file, b_file, output_file):
    """
    根据JSON文件a中的顺序重新排列JSON文件b中的数据,并将结果保存到输出文件中。

    参数:
    :param a_file: 包含数据排序顺序的JSON文件路径。
    :param b_file: 需要重新排序的JSON文件路径。
    :param output_file: 保存重新排序后数据的JSON文件路径。
    """
    try:
        # 加载a文件中的数据,用于获取数据排序顺序
        with open(a_file, 'r') as file:
            a_data = json.load(file)

        # 加载b文件中的数据,用于建立哈希值到文件名的映射
        with open(b_file, 'r') as file:
            b_data = json.load(file)

        # 建立哈希值到文件名的映射
        b_hash_to_name = {value: key for key, value in b_data.items()}

        # 根据a.json中的哈希值顺序重新排列b.json中的数据
        sorted_b_data = {b_hash_to_name.get(hash_value, hash_value): hash_value for hash_value in a_data.values() if hash_value in b_hash_to_name}

        # 将重新排列后的数据保存到输出文件中
        with open(output_file, 'w') as file:
            json.dump(sorted_b_data, file, indent=4)
            print(f"排列结果已保存到 {output_file}")

    except FileNotFoundError as e:
        print(f"文件未找到: {e}")
    except json.JSONDecodeError:
        print("JSON文件格式错误,请检查输入文件。")
    except Exception as e:
        print(f"发生错误: {e}")

实例

from 批量命名.函数.main import file_rename
from 哈希工具.哈希计算 import calculate_hash
from 哈希工具.哈希排序 import hash_sorting

target_directory = r"D:\Pictures\download\photos\image"
backup_directory = r"D:\Pictures\download\photos\backup"
start_file_prefix = ""
end_file_prefix = "image-"
valid_extensions = ['.png', '.jpg', '.jpeg', '.gif', '.bmp', '.webp']
length = 4
a_file = r'a.json'
b_file = r'b.json'
output_file = r'c.json'


# 调用函数
file_rename(target_directory, backup_directory, None, valid_extensions, length, mode='sequential')
calculate_hash(backup_directory, a_file)
file_rename(None, backup_directory, None, valid_extensions, length, mode='date_random_char')
calculate_hash(backup_directory, b_file)
hash_sorting(a_file, b_file, output_file)

1

评论区