python
安装python
python下载地址,安装时一定要选择Add Python to PATH(否则命令行无法识别python命令)
下载python后运行
python --version查看python是否安装成功
创建python文件,name.py
在文件所在的文件夹下cmd,运行命令python name.py运行python代码
运行时会没反应,如不打印print输出内容
运行type name.py查看是否有乱码,如果有乱码说明文件不是utf-8,在文件头部添加如下内容
# -*- coding: utf-8 -*-结合使用,网站批量下载图片,根据数组图片名称顺序修改文件夹内图片名称
如将abc45635.jpg修改为1.jpg
谷歌浏览器添加扩展工具Download All Images 3.1.0.crx(在工具文件夹),批量下载漫画图片
下载后的图片名不是按顺序排列的且图片名一长串abc45635.jpg
在控制台找到按顺序的图片代码右键 -> copy -> copy Element,写个函数处理一下把图片的名字按顺序生成个数组,代码如下:
<script>
const htmlString = `
<div class="comic-contain"><div class="comic-contain__item" data-pid="0" data-index="0">
<img class="lazy-read" src="blob:https://www.manhua55.com/9c6bd774-3382-47b6-9fce-14762995ad18" data-src="/static/upload2/book/id/335002/30864568/90bedc3892ee731e5d5310159f9460c4_zb.webp" referrerpolicy="no-referrer">
</div><div class="comic-contain__item" data-pid="1" data-index="1">
<img class="lazy-read" src="blob:https://www.manhua55.com/f2aff142-aa14-47a8-950b-82837808adaa" data-src="/static/upload2/book/id/335002/30864568/d418ccc34c18f554655b760d3525e56c_zb.webp" referrerpolicy="no-referrer">
</div>`;
// 创建一个临时DOM元素来解析HTML字符串
const tempDiv = document.createElement('div');
tempDiv.innerHTML = htmlString;
// 获取所有img元素
const imgElements = tempDiv.querySelectorAll('img[src^="blob:https://www.manhua55.com/"]');
// 提取blob:后面的字符串并生成数组
const blobIds = Array.from(imgElements).map(img => {
const src = img.getAttribute('src');
// 提取blob:https://www.manhua55.com/后面的部分
return src.replace('blob:https://www.manhua55.com/', '');
});
console.log(blobIds); // 输出: ["9c6bd774-3382-47b6-9fce-14762995ad18"]
</script>在浏览器运行,通过console获取数组,右键复制数组,替换到python文件里,运行python自动改名完成
之后写个重命名的python文件,文件和图片放在同一个文件夹下,如以下代码放在G盘text文件夹下
把图片名数组替换以下targets = ['a', 'b', 'c'] # 需要完全匹配的字符串
在文件夹目录上输入cmd,然后运行python name.py
# -*- coding: utf-8 -*-
print("===== 调试信息 =====")
import os
def rename_files_by_exact_match(folder_path, target_strings):
files = os.listdir(folder_path)
print("找到文件列表:", files)
for filename in files:
name_part, ext = os.path.splitext(filename)
print(f"\n检查文件: {filename} → 分离为: ('{name_part}', '{ext}')")
if name_part in target_strings:
index = target_strings.index(name_part)
new_name = f"{index}{ext}"
old_path = os.path.join(folder_path, filename)
new_path = os.path.join(folder_path, new_name)
print(f"匹配成功! 将重命名为: {new_name}")
os.rename(old_path, new_path)
else:
print("未匹配目标字符串")
print("\n=== 处理完成 ===")
# 使用示例
folder = r"G:\text" # 替换为你的实际路径
targets = ['a', 'b', 'c'] # 需要完全匹配的字符串
print("===== 调试信息 =====")
print("文件夹是否存在:", os.path.exists(folder))
rename_files_by_exact_match(folder, targets)
input("按回车退出...")创建test.py文件在该目录下cmd用python test.py运行无反应,在其他目录(之前成功运行python的目录)中自动复制了此test.py文件,在该文件夹下运行python正常,解决方案如下
造成此原因是有多个python.exe文件,造成干扰导致运行python时运行的不是正常的python优先级被打乱
在有问题的文件夹下cmd输入
where python如果显示有两个python.exe文件,判断哪个是正常的python通常带Microsoft\WindowsApps的是应用商店自己下载的python,如果不能判断可以让ai辅助判断,然后运行如下代码删除此项
del "C:\Users\Afand\AppData\Local\Microsoft\WindowsApps\python.exe"之后再运行如下代码
where python
python -c "print('Hello')"能正常输出了即可
运行python文件,实现输入文件名,把包含该文件名的所有子文件都移动到新创建的同名文件夹下
实现在当前目录下运行python文件,输入要移动的txt文件名称,将当前目录所有文件夹内的子文件包含该文件名的txt文件都移动到根据输入的名称创建的文件夹下
如输入“测试”,则当前文件夹下所有子文件包含“测试”的文件都移动到新创建的测试文件夹下,具体代码如下
import os
import shutil
from pathlib import Path
def organize_files_recursive():
keyword = input("请输入要搜索的文件名关键字:").strip()
if not keyword:
return
target_folder = Path(keyword)
if not target_folder.exists():
target_folder.mkdir()
current_dir = Path('.').resolve()
target_path_resolved = target_folder.resolve()
moved_files = []
print(f"当前目录: {current_dir}")
print(f"目标文件夹: {target_path_resolved}")
print("-" * 50)
for root, dirs, files in os.walk('.', topdown=True):
# 将root转换为绝对路径进行比较
root_abs = Path(root).resolve()
# 使用绝对路径比较,确保只跳过目标文件夹
if root_abs == target_path_resolved:
print(f"跳过的确实是目标文件夹: {root_abs}")
# 从遍历列表中移除,避免遍历目标文件夹内部
if root in dirs:
dirs.remove(root)
continue
for file in files:
if keyword in file:
source_abs = root_abs / file
# 再次确认不是目标文件夹内的文件
try:
# 检查文件是否已经在目标文件夹中
if source_abs.parent == target_path_resolved:
print(f"跳过已在目标文件夹中的文件: {file}")
continue
except:
pass
target_file = target_folder / file
# 处理重名
counter = 1
while target_file.exists():
name, ext = os.path.splitext(file)
target_file = target_folder / f"{name}_{counter}{ext}"
counter += 1
try:
shutil.move(str(source_abs), str(target_file))
# 显示相对路径
rel_source = source_abs.relative_to(current_dir) if source_abs.is_relative_to(current_dir) else source_abs
moved_files.append(str(rel_source))
print(f"✓ 已移动: {rel_source}")
except Exception as e:
print(f"✗ 移动失败 {file}: {e}")
if moved_files:
print(f"\n✓ 完成!移动了 {len(moved_files)} 个文件")
else:
print(f"\n⚠ 未找到文件")
if __name__ == "__main__":
organize_files_recursive()
input("\n按回车退出")运行python文件,实现输入多个文件名如(文件名1,文件名2...),分别把包含文件名的所有子文件都移动到和py所在文件夹的同级名为chuli的文件夹下的新创建的同名文件夹下
在对应py文件的文件夹下cmd,然后输入python 文件名.py运行该文件,根据提示输入要操作的文件名
import os
import shutil
from pathlib import Path
def organize_files_recursive():
# 输入多个关键字,用逗号分隔
keywords_input = input("请输入要搜索的文件名关键字(多个关键字请用逗号分隔,如:文件1,文件2,文件3):").strip()
if not keywords_input:
return
# 分割关键字并去除空格
keywords = [kw.strip() for kw in keywords_input.split(',') if kw.strip()]
if not keywords:
return
# 获取py文件所在目录的上一级目录(同级目录)
script_dir = Path(__file__).parent.resolve()
chuli_dir = script_dir.parent / 'chuli' # py文件所在文件夹的同级文件夹中的chuli文件夹
# 创建chuli文件夹(如果不存在)
if not chuli_dir.exists():
chuli_dir.mkdir(parents=True)
print(f"创建文件夹: {chuli_dir}")
# 为每个关键字创建对应的文件夹并移动文件
for keyword in keywords:
print(f"\n{'='*60}")
print(f"正在处理关键字: {keyword}")
print(f"{'='*60}")
# 在chuli文件夹中创建关键字文件夹
target_folder = chuli_dir / keyword
if not target_folder.exists():
target_folder.mkdir()
current_dir = Path('.').resolve()
target_path_resolved = target_folder.resolve()
moved_files = []
print(f"当前工作目录: {current_dir}")
print(f"目标文件夹: {target_path_resolved}")
print("-" * 50)
for root, dirs, files in os.walk('.', topdown=True):
# 将root转换为绝对路径进行比较
root_abs = Path(root).resolve()
# 跳过chuli文件夹(避免重复遍历)
if root_abs == chuli_dir.resolve() or chuli_dir.resolve() in root_abs.parents:
if root in dirs:
dirs.clear()
continue
# 跳过所有关键字对应的文件夹(避免重复遍历)
skip_folders = [(chuli_dir / kw).resolve() for kw in keywords if (chuli_dir / kw).exists()]
if root_abs in skip_folders:
# 从遍历列表中移除该文件夹的子目录
if root in dirs:
dirs.clear() # 清空子目录列表,避免遍历
continue
for file in files:
if keyword in file:
source_abs = root_abs / file
# 检查文件是否已经在目标文件夹中
if source_abs.parent == target_path_resolved:
print(f"跳过已在目标文件夹中的文件: {file}")
continue
target_file = target_folder / file
# 处理重名
counter = 1
while target_file.exists():
name, ext = os.path.splitext(file)
target_file = target_folder / f"{name}_{counter}{ext}"
counter += 1
try:
shutil.move(str(source_abs), str(target_file))
# 显示相对路径
rel_source = source_abs.relative_to(current_dir) if source_abs.is_relative_to(current_dir) else source_abs
moved_files.append(str(rel_source))
print(f"✓ 已移动: {rel_source}")
except Exception as e:
print(f"✗ 移动失败 {file}: {e}")
if moved_files:
print(f"\n✓ 关键字 '{keyword}' 完成!移动了 {len(moved_files)} 个文件")
print(f" 文件已移动到: {target_folder}")
else:
print(f"\n⚠ 未找到包含 '{keyword}' 的文件")
print(f"\n{'='*60}")
print(f"所有关键字处理完成!")
print(f"所有文件已移动到: {chuli_dir}")
if __name__ == "__main__":
organize_files_recursive()
input("\n按回车退出")修改当前文件夹下的子文件夹的名称,如将《书名》或2019-0-1《书名》或《书名》这是一本书或【新】书名【读书站】或2018-08书名或2018-08 书名或02 书名或2.书名或02书名或www.edo.cn - 书名或①书名修改成书名,其中子文件夹下的文件内容不变
创建一个rename_folders.py文件,内容如下,在该文件的目录上输入cmd回车,再输入python rename_folders.py运行该文件,按提示操作即可,此代码遇到重复的文件名即不做处理,如文件夹下有子文件夹书名和子文件夹《书名》,则《书名》会被保留,方便自己做相同文件的处理(把保留的文件移动到其他文件夹下处理再移动回来去重)
import os
import re
def process_folder_name(name):
"""根据规则处理文件夹名称"""
original_name = name
# 1. 优先提取《》内部的内容(如果存在)
match = re.search(r'《([^》]*)》', name)
if match:
name = match.group(1)
# 2. 删除所有【xxx】格式的内容
name = re.sub(r'【[^】]*】', '', name)
# 3. 去除开头的各种前缀(日期、数字编号、特殊符号等)
# 3.1 去除开头的日期格式:YYYY-MM 或 YYYY-M 或 YYYY年MM月 等
name = re.sub(r'^\d{4}[-年]\d{1,2}[月]?\s*', '', name)
# 3.2 去除开头的数字范围:如 "1-4." 或 "1-4、" 等
name = re.sub(r'^\d+[-~]\d+[\.、]?\s*', '', name)
# 3.3 去除开头的数字 + 点 + 可选空格:如 "1." 或 "01." 或 "1. "
name = re.sub(r'^\d+(?:\.|、)\s*', '', name)
# 3.4 去除开头的数字 + 可选空格(无点):如 "01 " 或 "1 " 或 "02"(数字直接连文字)
name = re.sub(r'^\d+\s*', '', name)
# 3.5 去除开头的带圈数字:① ② ③ 等
name = re.sub(r'^[①②③④⑤⑥⑦⑧⑨⑩⑪⑫⑬⑭⑮⑯⑰⑱⑲⑳]\s*', '', name)
# 3.6 去除开头的罗马数字(简单版):I. II. III. 等
name = re.sub(r'^[IVXLCDM]+\.\s*', '', name)
# 4. 去除开头的网站/来源标识(如 "ePUBw.COM - "、"xxx.com - " 等)
# 匹配模式:任意字符(不含换行)+ 空格 + 减号 + 空格
name = re.sub(r'^[A-Za-z0-9\.]+(\s*-\s*|\s+-\s+)', '', name)
# 更通用的匹配:xxx.xxx - 或 xxx - 格式
name = re.sub(r'^[A-Za-z0-9\.]+\s*-\s*', '', name)
# 5. 处理 "xxx_中文描述" 格式(如果没有书名号的情况)
if '_' in name and not match:
name = name.split('_')[0]
# 6. 处理括号内的描述(如 (珍藏版))-> 删除
name = re.sub(r'\([^)]*\)', '', name)
name = re.sub(r'([^)]*)', '', name)
# 7. 处理套装描述
name = re.sub(r'套装[共\d册]*', '', name)
# 8. 处理 + 号(保留,但清理两边空格)
name = re.sub(r'\s*\+\s*', '+', name)
# 9. 删除首尾空格
name = name.strip()
# 10. 删除多余的空格(连续多个空格变成单个)
name = re.sub(r'\s+', ' ', name)
# 如果处理后是空字符串,恢复原名称
if not name:
name = original_name
return name
def rename_folders():
"""处理当前py文件所在文件夹下的子文件夹名称"""
current_dir = os.path.dirname(os.path.abspath(__file__))
print(f"工作目录: {current_dir}")
print("-" * 60)
try:
items = os.listdir(current_dir)
folders = [item for item in items
if os.path.isdir(os.path.join(current_dir, item))]
except PermissionError:
print("错误:没有权限读取当前目录")
return
if not folders:
print("当前目录下没有子文件夹")
return
# 预览修改
print("预览修改(不执行实际重命名):")
print("-" * 60)
changes = []
for folder in folders:
new_name = process_folder_name(folder)
if new_name != folder:
changes.append((folder, new_name))
print(f"原名称: {folder}")
print(f"新名称: {new_name}")
print("-" * 40)
if not changes:
print("没有需要修改的文件夹名称")
return
print(f"\n共发现 {len(changes)} 个文件夹需要重命名")
confirm = input("是否执行重命名?(y/n): ").strip().lower()
if confirm != 'y':
print("已取消重命名操作")
return
print("\n开始重命名...")
success_count = 0
for old_name, new_name in changes:
old_path = os.path.join(current_dir, old_name)
new_path = os.path.join(current_dir, new_name)
if os.path.exists(new_path):
print(f"跳过 {old_name} -> {new_name} (目标已存在)")
continue
try:
os.rename(old_path, new_path)
print(f"✓ {old_name} -> {new_name}")
success_count += 1
except Exception as e:
print(f"✗ 重命名失败 {old_name}: {e}")
print(f"\n完成!成功重命名 {success_count}/{len(changes)} 个文件夹")
if __name__ == "__main__":
rename_folders()如果不需要去重,需要把书名和《书名》文件夹合并成书名,并且重复文件自动修改名字的代码如下
import os
import re
import shutil
def process_folder_name(name):
"""根据规则处理文件夹名称"""
original_name = name
# 1. 优先提取《》内部的内容(如果存在)
match = re.search(r'《([^》]*)》', name)
if match:
name = match.group(1)
# 2. 删除所有【xxx】格式的内容
name = re.sub(r'【[^】]*】', '', name)
# 3. 去除开头的各种前缀(日期、数字编号、特殊符号等)
# 3.1 去除开头的日期格式:YYYY-MM 或 YYYY-M 或 YYYY年MM月 等
name = re.sub(r'^\d{4}[-年]\d{1,2}[月]?\s*', '', name)
# 3.2 去除开头的数字范围:如 "1-4." 或 "1-4、" 等
name = re.sub(r'^\d+[-~]\d+[\.、]?\s*', '', name)
# 3.3 去除开头的数字 + 点 + 可选空格:如 "1." 或 "01." 或 "1. "
name = re.sub(r'^\d+(?:\.|、)\s*', '', name)
# 3.4 去除开头的数字 + 可选空格(无点):如 "01 " 或 "1 " 或 "02"(数字直接连文字)
name = re.sub(r'^\d+\s*', '', name)
# 3.5 去除开头的带圈数字:① ② ③ 等
name = re.sub(r'^[①②③④⑤⑥⑦⑧⑨⑩⑪⑫⑬⑭⑮⑯⑰⑱⑲⑳]\s*', '', name)
# 3.6 去除开头的罗马数字(简单版):I. II. III. 等
name = re.sub(r'^[IVXLCDM]+\.\s*', '', name)
# 4. 去除开头的网站/来源标识(如 "ePUBw.COM - "、"xxx.com - " 等)
name = re.sub(r'^[A-Za-z0-9\.]+(\s*-\s*|\s+-\s+)', '', name)
name = re.sub(r'^[A-Za-z0-9\.]+\s*-\s*', '', name)
# 5. 处理 "xxx_中文描述" 格式(如果没有书名号的情况)
if '_' in name and not match:
name = name.split('_')[0]
# 6. 处理括号内的描述(如 (珍藏版))-> 删除
name = re.sub(r'\([^)]*\)', '', name)
name = re.sub(r'([^)]*)', '', name)
# 7. 处理套装描述
name = re.sub(r'套装[共\d册]*', '', name)
# 8. 处理 + 号(保留,但清理两边空格)
name = re.sub(r'\s*\+\s*', '+', name)
# 9. 删除首尾空格
name = name.strip()
# 10. 删除多余的空格(连续多个空格变成单个)
name = re.sub(r'\s+', ' ', name)
# 如果处理后是空字符串,恢复原名称
if not name:
name = original_name
return name
def merge_folders(source_path, target_path):
"""将源文件夹的内容合并到目标文件夹"""
try:
# 遍历源文件夹中的所有内容
for item in os.listdir(source_path):
source_item = os.path.join(source_path, item)
target_item = os.path.join(target_path, item)
# 如果是文件,直接移动
if os.path.isfile(source_item):
# 如果目标文件已存在,添加后缀避免覆盖
if os.path.exists(target_item):
base, ext = os.path.splitext(item)
counter = 1
while os.path.exists(os.path.join(target_path, f"{base}_{counter}{ext}")):
counter += 1
target_item = os.path.join(target_path, f"{base}_{counter}{ext}")
shutil.move(source_item, target_item)
# 如果是文件夹,递归合并
elif os.path.isdir(source_item):
if os.path.exists(target_item):
# 递归合并子文件夹
merge_folders(source_item, target_item)
else:
# 直接移动整个文件夹
shutil.move(source_item, target_item)
# 删除空的源文件夹
if os.path.exists(source_path) and not os.listdir(source_path):
os.rmdir(source_path)
else:
# 如果不是空的,尝试强制删除(理论上上面已经移完所有内容)
try:
os.rmdir(source_path)
except OSError:
print(f" 警告:无法删除 {source_path},可能还有残留文件")
return True
except Exception as e:
print(f" 合并失败:{e}")
return False
def rename_folders():
"""处理当前py文件所在文件夹下的子文件夹名称"""
current_dir = os.path.dirname(os.path.abspath(__file__))
print(f"工作目录: {current_dir}")
print("-" * 60)
try:
items = os.listdir(current_dir)
folders = [item for item in items
if os.path.isdir(os.path.join(current_dir, item))]
except PermissionError:
print("错误:没有权限读取当前目录")
return
if not folders:
print("当前目录下没有子文件夹")
return
# 第一步:预览所有修改
print("预览修改:")
print("-" * 60)
changes = [] # 存储 (原名称, 新名称, 是否需要合并)
merge_pairs = [] # 存储需要合并的 (源文件夹, 目标文件夹)
for folder in folders:
new_name = process_folder_name(folder)
if new_name != folder:
changes.append((folder, new_name))
print(f"原名称: {folder}")
print(f"新名称: {new_name}")
print("-" * 40)
if not changes:
print("没有需要修改的文件夹名称")
return
# 第二步:检查并建立需要合并的映射关系
# 构建原名称到新名称的映射
rename_map = {old: new for old, new in changes}
# 查找冲突:新名称已存在(且不是重命名自身)
for old_name, new_name in changes:
if new_name in folders and new_name != old_name:
# 需要将 old_name 合并到已存在的 new_name
merge_pairs.append((old_name, new_name))
print(f"\n⚠️ 检测到冲突:")
print(f" 源文件夹: {old_name}")
print(f" 目标文件夹: {new_name} (已存在)")
print(f" 将合并内容并删除 {old_name}")
# 第三步:询问用户确认
print(f"\n共发现 {len(changes)} 个文件夹需要处理")
if merge_pairs:
print(f"其中 {len(merge_pairs)} 个需要合并到已存在的文件夹")
confirm = input("\n是否执行操作?(y/n): ").strip().lower()
if confirm != 'y':
print("已取消操作")
return
# 第四步:执行合并操作
print("\n开始处理...")
success_merge = 0
for source_name, target_name in merge_pairs:
source_path = os.path.join(current_dir, source_name)
target_path = os.path.join(current_dir, target_name)
print(f"\n合并: {source_name} -> {target_name}")
if not os.path.exists(source_path):
print(f" 跳过:源文件夹不存在")
continue
if not os.path.exists(target_path):
print(f" 跳过:目标文件夹不存在")
continue
if merge_folders(source_path, target_path):
print(f" ✓ 合并成功")
success_merge += 1
else:
print(f" ✗ 合并失败")
# 第五步:执行重命名(只处理没有冲突的)
print("\n执行重命名...")
success_rename = 0
for old_name, new_name in changes:
# 跳过已经被合并的文件夹
if any(old_name == pair[0] for pair in merge_pairs):
continue
old_path = os.path.join(current_dir, old_name)
new_path = os.path.join(current_dir, new_name)
# 检查目标是否已存在(再次确认)
if os.path.exists(new_path):
print(f"跳过 {old_name} -> {new_name} (目标已存在,需要手动处理)")
continue
try:
os.rename(old_path, new_path)
print(f"✓ {old_name} -> {new_name}")
success_rename += 1
except Exception as e:
print(f"✗ 重命名失败 {old_name}: {e}")
print(f"\n完成!")
print(f" - 成功合并: {success_merge}/{len(merge_pairs)} 个文件夹")
print(f" - 成功重命名: {success_rename}/{len(changes) - len(merge_pairs)} 个文件夹")
if __name__ == "__main__":
rename_folders()简单处理网文文件标题
先生成当前文件夹下的文件标题文件用powershell Get-ChildItem -Name > 11.txt
然后创建个first_title.py,在当前文件夹运行,输入要处理的文件名11.txt
再创建个second_title.py,在当前文件夹运行,输入要处理的文件名output_清理后的书名.txt,后输出的valid_titles.txt为大致处理好的标题名可以直接用整理文件的py批量输入使用,输出的invalid_titles.txt可进行二次处理
其中代码如下:
import os
import re
def clean_title(title: str) -> str:
"""
清理书名,删除指定模式和符号
"""
# 保存原始标题用于最后的处理
original_title = title
# 1. 首先处理文件名中的".txt"扩展名
if title.endswith('.txt'):
title = title[:-4]
elif '.' in title:
title = title.rsplit('.', 1)[0]
# 2. 删除"作者:"或"作家:"及其后面的所有内容(使用字符串分割)
if '作者:' in title:
title = title.split('作者:')[0]
if '作者:' in title:
title = title.split('作者:')[0]
if '作家:' in title:
title = title.split('作家:')[0]
if '作家:' in title:
title = title.split('作家:')[0]
# 3. 删除各种括号及其内部的所有内容
brackets = [
('[', ']'), ('[', ']'), ('【', '】'), ('(', ')'),
('(', ')'), ('〖', '〗'), ('『', '』'), ('「', '」'),
('{', '}'), ('<', '>'), ('《', '》')
]
for left, right in brackets:
pattern = f'\\{left}[^{right}]*\\{right}'
title = re.sub(pattern, '', title)
# 4. 删除《以及该符号前的所有内容
if '《' in title:
title = title.split('《', 1)[-1]
# 5. 删除》以及该符号后的所有内容
if '》' in title:
title = title.split('》', 1)[0]
# 6. 删除"."以及该符号后的所有内容
if '.' in title:
title = title.split('.', 1)[0]
if '。' in title:
title = title.split('。', 1)[0]
# 7. 删除各种格式的GL、BL、BG标签
tags_to_remove = [
'GL', 'Gl', 'gL', 'gl', # GL的各种写法
'BL', 'Bl', 'bL', 'bl', # BL的各种写法
'BG', 'Bg', 'bG', 'bg', # BG的各种写法
'百合', 'abo', 'ABO', 'np', 'NP', # 其他标签
]
for tag in tags_to_remove:
title = title.replace(tag, '')
# 8. 删除by及其后面的所有内容
if 'by' in title.lower():
by_index = title.lower().find('by')
title = title[:by_index]
if 'By' in title:
title = title.split('By')[0]
if 'BY' in title:
title = title.split('BY')[0]
# 9. 删除可能残留的括号内容
title = re.sub(r'[((][^))]*[))]', '', title)
# 10. 删除"(番外完)"等标记
title = re.sub(r'[((]番外.*?[))]', '', title)
title = re.sub(r'[((]完结.*?[))]', '', title)
# 11. 删除首尾多余的空格和符号
title = title.strip()
title = title.strip(',,。!?、::;;')
# 12. 清理连续的空格
title = re.sub(r'\s+', ' ', title)
title = title.strip()
# 13. 删除末尾的数字(如章节号)
title = re.sub(r'\s*\d+\s*$', '', title)
# 14. 如果处理后为空,尝试从原标题提取
if not title or len(title) < 2:
# 提取中文字符
chinese_chars = re.findall(r'[\u4e00-\u9fff]+', original_title)
if chinese_chars:
# 取最长的中文连续字符串
title = max(chinese_chars, key=len)
else:
return "无法识别"
return title
def read_file_with_encoding(file_path):
"""尝试多种编码读取文件"""
encodings_to_try = ['utf-8', 'gbk', 'gb2312', 'gb18030', 'utf-16']
for enc in encodings_to_try:
try:
with open(file_path, 'r', encoding=enc) as f:
lines = [line.strip() for line in f if line.strip()]
print(f"成功使用编码: {enc}")
return lines
except (UnicodeDecodeError, LookupError):
continue
# 最后尝试二进制读取并忽略错误
try:
with open(file_path, 'rb') as f:
raw_data = f.read()
content = raw_data.decode('utf-8', errors='ignore')
lines = [line.strip() for line in content.splitlines() if line.strip()]
print("使用UTF-8(忽略错误)读取成功")
return lines
except:
pass
return []
def process_file():
"""
处理文件:读取、清理标题、去重、输出新文件
"""
# 获取脚本所在目录
base_dir = os.path.dirname(os.path.abspath(__file__))
# 输入文件名
input_name = input("请输入要处理的文件名(如 11.txt):").strip()
input_path = os.path.join(base_dir, input_name)
if not os.path.exists(input_path):
print(f"错误:文件 {input_path} 不存在,请检查文件名。")
return
# 读取文件内容
lines = read_file_with_encoding(input_path)
if not lines:
print("无法读取文件内容,请检查文件格式。")
return
print(f"\n共读取到 {len(lines)} 行内容")
print("="*60)
# 处理每一行
cleaned_titles = []
for i, line in enumerate(lines, 1):
original = line
cleaned = clean_title(line)
# 只保存有效的书名
if cleaned and cleaned != "无法识别" and len(cleaned) >= 2:
cleaned_titles.append(cleaned)
print(f"{i}. 原: {original}")
print(f" 新: {cleaned}")
print("-" * 40)
else:
print(f"{i}. 跳过无效内容: {original}")
print("-" * 40)
if not cleaned_titles:
print("\n警告:没有提取到有效的书名!")
return
# 去重(保持第一次出现的顺序)
unique_titles = []
seen = set()
for title in cleaned_titles:
if title not in seen:
unique_titles.append(title)
seen.add(title)
print(f"\n去重前: {len(cleaned_titles)} 个书名")
print(f"去重后: {len(unique_titles)} 个唯一书名")
# 输出到新文件
output_name = "output_清理后的书名.txt"
output_path = os.path.join(base_dir, output_name)
with open(output_path, 'w', encoding='utf-8') as f:
for title in unique_titles:
f.write(title + '\n')
print(f"\n{'='*60}")
print(f"处理完成!")
print(f"结果已保存至:{output_path}")
print(f"共处理 {len(lines)} 行,成功提取 {len(cleaned_titles)} 个有效书名,去重后剩余 {len(unique_titles)} 个")
print(f"{'='*60}")
# 显示最终结果
print("\n最终去重后的书名列表:")
for i, title in enumerate(unique_titles, 1):
print(f"{i:2d}. {title}")
if __name__ == "__main__":
process_file()import os
import re
def is_valid_title(title: str) -> bool:
"""
检查标题是否符合规则:
标题中间不含有空格、-(短横线)、-(全角短横线)、+(加号)、
_(下划线)、@(at符号)、冒号(中英文)、单引号(中英文)、双引号(中英文)
"""
# 定义不允许出现的符号
invalid_patterns = [
r'\s', # 空格
r'-', # 短横线(半角)
r'-', # 短横线(全角)
r'\+', # 加号(需要转义)
r'_', # 下划线
r'@', # at符号
r':', # 中文冒号
r':', # 英文冒号
r'‘', # 中文左单引号
r'’', # 中文右单引号
r'`', # 反引号
r"'", # 英文单引号
r'"', # 英文双引号
r'“', # 中文左双引号
r'”', # 中文右双引号
]
for pattern in invalid_patterns:
if re.search(pattern, title):
return False
return True
def process_file():
"""
处理文件:筛选符合和不符合规则的标题
"""
# 获取脚本所在目录
base_dir = os.path.dirname(os.path.abspath(__file__))
# 输入文件名
input_name = input("请输入要处理的文件名(如 output_清理后的书名.txt):").strip()
input_path = os.path.join(base_dir, input_name)
if not os.path.exists(input_path):
print(f"错误:文件 {input_path} 不存在,请检查文件名。")
return
# 尝试读取文件(支持多种编码)
lines = []
encodings_to_try = ['utf-8', 'gbk', 'gb2312', 'gb18030']
for enc in encodings_to_try:
try:
with open(input_path, 'r', encoding=enc) as f:
lines = [line.strip() for line in f if line.strip()]
print(f"成功使用编码: {enc}")
break
except (UnicodeDecodeError, LookupError):
continue
if not lines:
# 最后尝试忽略错误
try:
with open(input_path, 'rb') as f:
content = f.read().decode('utf-8', errors='ignore')
lines = [line.strip() for line in content.splitlines() if line.strip()]
print("使用UTF-8(忽略错误)读取成功")
except:
print("无法读取文件,请检查文件格式。")
return
print(f"\n共读取到 {len(lines)} 行内容")
print("="*60)
# 分类标题
valid_titles = [] # 符合规则的标题
invalid_titles = [] # 不符合规则的标题
for line in lines:
if is_valid_title(line):
valid_titles.append(line)
print(f"✓ 符合规则: {line}")
else:
invalid_titles.append(line)
print(f"✗ 不符合规则: {line}")
print("="*60)
# 处理符合规则的标题:按长度从长到短排序
valid_titles.sort(key=lambda x: len(x), reverse=True)
# 用英文逗号分隔,不换行
valid_output = ','.join(valid_titles)
# 不符合规则的标题:保持原格式,每个标题换一行
invalid_output = '\n'.join(invalid_titles)
# 输出符合规则的标题文件
valid_output_name = "valid_titles.txt"
valid_output_path = os.path.join(base_dir, valid_output_name)
with open(valid_output_path, 'w', encoding='utf-8') as f:
f.write(valid_output)
# 输出不符合规则的标题文件
invalid_output_name = "invalid_titles.txt"
invalid_output_path = os.path.join(base_dir, invalid_output_name)
with open(invalid_output_path, 'w', encoding='utf-8') as f:
f.write(invalid_output)
# 输出统计信息
print(f"\n处理完成!")
print(f"="*60)
print(f"总标题数: {len(lines)}")
print(f"符合规则的标题数: {len(valid_titles)} (已按长度从长到短排序)")
print(f"不符合规则的标题数: {len(invalid_titles)} (保持原格式)")
print(f"="*60)
print(f"符合规则的标题已保存至: {valid_output_path}")
print(f"不符合规则的标题已保存至: {invalid_output_path}")
print(f"="*60)
# 显示符合规则的标题预览
if valid_titles:
print("\n符合规则的标题(按长度从长到短):")
for i, title in enumerate(valid_titles, 1):
print(f"{i:2d}. {title} (长度: {len(title)})")
print(f"\n逗号分隔格式:")
print(valid_output)
# 显示不符合规则的标题预览
if invalid_titles:
print(f"\n不符合规则的标题(共{len(invalid_titles)}个):")
for i, title in enumerate(invalid_titles, 1):
print(f"{i:2d}. {title}")
if __name__ == "__main__":
process_file()暴力破解压缩包密码
创建unzip_tool.py文件代码如下,确保电脑装了7-zip压缩app,运行代码直接按提示输入密码长度,可以在代码中添加常用密码,先使用常用密码破解,不成功使用暴力密码破解
根据提示输入密码长度,输入密码规则,输入起始密码或不填从头开始,然后破解即可。中通想停止可以用ctrl+c停止破解,会显示已经破解的进度和密码,可以记录当前破解密码,下次从此密码开始破解。
import os
import sys
import subprocess
import itertools
import time
import signal
from pathlib import Path
# 全局变量用于控制停止
stop_flag = False
current_testing_password = ""
def signal_handler(sig, frame):
"""处理Ctrl+C信号"""
global stop_flag, current_testing_password
stop_flag = True
print(f"\n\n用户请求停止... 当前正在测试密码: {current_testing_password}")
print("正在保存进度并退出...")
def find_7zip():
"""查找7-Zip安装路径"""
common_paths = [
r"C:\Program Files\7-Zip\7z.exe",
r"C:\Program Files (x86)\7-Zip\7z.exe",
r"D:\Program Files\7-Zip\7z.exe",
r"D:\Program Files (x86)\7-Zip\7z.exe",
]
for path in common_paths:
if Path(path).exists():
return path
try:
result = subprocess.run(['where', '7z'], capture_output=True, text=True)
if result.returncode == 0:
return result.stdout.strip().split('\n')[0]
except:
pass
return None
def parse_password_rule(rule_input, specified_length):
"""
解析密码规则
规则示例:
- "0" : 纯数字
- "a" : 纯小写字母
- "A" : 纯大写字母
- "0a" : 数字和小写字母(包括纯数字和纯字母)
- "0aA" : 数字、大小写字母(包括纯组合)
- "0aA,.!" : 数字、大小写字母、特殊字符(包括纯组合)
- "-0a" : 数字和小写字母的混合(排除纯数字和纯字母)
- "-0aA" : 数字、大小写字母混合(排除纯数字、纯小写、纯大写)
- "-0aA,.!" : 数字、大小写字母、特殊字符混合(排除纯字符组合)
"""
# 检查是否为混合模式(排除纯字符组合)
mixed_mode = False
if rule_input.startswith('-'):
mixed_mode = True
rule_input = rule_input[1:] # 移除前缀
char_sets = {
'0': '0123456789',
'a': 'abcdefghijklmnopqrstuvwxyz',
'A': 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
}
# 收集字符集
chars = []
special_chars = []
selected_types = [] # 记录选择了哪些类型
i = 0
while i < len(rule_input):
char = rule_input[i]
if char in char_sets:
chars.append(char_sets[char])
selected_types.append(char)
i += 1
else:
# 收集特殊字符
special_start = i
while i < len(rule_input) and rule_input[i] not in '0aA':
i += 1
special_chars.append(rule_input[special_start:i])
if special_chars[-1]:
selected_types.append('special')
# 合并所有字符集
all_chars = ''.join(chars)
if special_chars:
all_chars += ''.join(special_chars)
# 如果没有选择任何字符集,默认使用数字
if not all_chars:
all_chars = '0123456789'
selected_types = ['0']
print("未指定字符集,默认使用数字(0-9)")
# 去重并保持顺序
all_chars = ''.join(sorted(set(all_chars), key=all_chars.index))
return specified_length, all_chars, mixed_mode, selected_types, special_chars
def is_pure_combo(password, selected_types, special_chars):
"""
检查密码是否为纯字符组合(只包含单一字符集)
Args:
password: 密码字符串
selected_types: 选择的类型列表,如 ['0', 'a'] 或 ['0', 'a', 'special']
special_chars: 特殊字符列表
"""
if not selected_types or len(selected_types) == 1:
return True
# 定义各类型的字符集
type_chars = {
'0': set('0123456789'),
'a': set('abcdefghijklmnopqrstuvwxyz'),
'A': set('ABCDEFGHIJKLMNOPQRSTUVWXYZ'),
}
# 添加特殊字符集
if special_chars:
special_set = set(''.join(special_chars))
type_chars['special'] = special_set
# 找出密码中包含哪些类型的字符
used_types = set()
for char in password:
for pwd_type, char_set in type_chars.items():
if char in char_set:
used_types.add(pwd_type)
break
# 如果只使用了单一类型,则是纯组合
return len(used_types) == 1
def string_to_index(password, char_set):
"""将密码字符串转换为索引"""
index = 0
for char in password:
index = index * len(char_set) + char_set.index(char)
return index
def index_to_string(index, length, char_set):
"""将索引转换为密码字符串"""
password = []
for i in range(length):
index, remainder = divmod(index, len(char_set))
password.append(char_set[remainder])
return ''.join(reversed(password))
def try_unzip(zip_path, password, extract_dir):
"""尝试用指定密码解压"""
cmd = [
seven_zip_path,
"x",
str(zip_path),
f"-o{extract_dir}",
"-y"
]
if password:
cmd.append(f"-p{password}")
try:
result = subprocess.run(
cmd,
capture_output=True,
text=True,
encoding='utf-8',
errors='ignore',
timeout=1 # 设置超时1秒
)
if result.returncode == 0:
return True, result.stdout
else:
return False, result.stderr
except subprocess.TimeoutExpired:
return False, "超时"
except Exception as e:
return False, str(e)
def brute_force_password(zip_path, length, char_set, extract_dir, mixed_mode, selected_types, special_chars, start_password=None):
"""
暴力破解密码
start_password: 起始密码,从该密码开始遍历(包含该密码)
"""
global stop_flag, current_testing_password
# 计算总组合数和起始索引
if start_password:
start_index = string_to_index(start_password, char_set)
total_combinations_raw = len(char_set) ** length
remaining_combinations = total_combinations_raw - start_index
print(f"\n从密码 '{start_password}' 开始遍历")
print(f"起始索引: {start_index:,}")
print(f"剩余需要尝试: {remaining_combinations:,} 个密码")
else:
start_index = 0
remaining_combinations = len(char_set) ** length
if mixed_mode:
print(f"\n开始混合模式暴力破解...")
print(f"密码长度: {length}")
print(f"字符集: {char_set}")
print(f"字符集大小: {len(char_set)}")
print(f"模式: 只尝试混合密码(排除纯字符组合)")
print("-" * 50)
else:
print(f"\n开始暴力破解...")
print(f"密码长度: {length}")
print(f"字符集: {char_set}")
print(f"字符集大小: {len(char_set)}")
print(f"总组合数: {remaining_combinations:,}")
print("-" * 50)
attempts = 0
start_time = time.time()
last_print_time = start_time
total_skipped = 0 # 跳过的纯组合数量
# 从起始索引开始生成密码
current_index = start_index
total = len(char_set) ** length
while current_index < total and not stop_flag:
# 将索引转换为密码
current_testing_password = index_to_string(current_index, length, char_set)
# 如果是混合模式,过滤掉纯组合
if mixed_mode and is_pure_combo(current_testing_password, selected_types, special_chars):
current_index += 1
total_skipped += 1
continue
attempts += 1
# 显示进度(每100次或每0.5秒显示一次)
current_time = time.time()
if attempts % 100 == 0 or current_time - last_print_time > 0.5:
elapsed = current_time - start_time
speed = attempts / elapsed if elapsed > 0 else 0
percent = ((current_index - start_index + 1) / remaining_combinations) * 100 if remaining_combinations > 0 else 0
if mixed_mode:
print(f"\r尝试次数: {attempts:,} | 速度: {speed:.0f} 密码/秒 | "
f"进度: {percent:.2f}% | 跳过纯组合: {total_skipped:,} | "
f"当前测试: {current_testing_password}", end='', flush=True)
else:
print(f"\r尝试进度: {percent:.2f}% ({attempts:,}/{remaining_combinations:,}) | "
f"速度: {speed:.0f} 密码/秒 | 当前测试: {current_testing_password}",
end='', flush=True)
last_print_time = current_time
# 尝试解压
success, output = try_unzip(zip_path, current_testing_password, extract_dir)
if success:
elapsed = time.time() - start_time
print(f"\n\n{'='*50}")
print(f"✓✓✓ 成功!密码正确!✓✓✓")
print(f"正确密码: {current_testing_password}")
print(f"尝试次数: {attempts:,}")
print(f"耗时: {elapsed:.2f} 秒")
print(f"{'='*50}")
return current_testing_password
current_index += 1
if stop_flag:
print(f"\n\n{'='*50}")
print(f"程序已停止")
print(f"最后一个测试的密码: {current_testing_password}")
print(f"已尝试密码数: {attempts:,}")
print(f"未找到正确密码")
print(f"{'='*50}")
return None
elapsed = time.time() - start_time
print(f"\n\n{'='*50}")
if mixed_mode:
print(f"✗ 破解失败!已尝试 {attempts:,} 个混合密码")
else:
print(f"✗ 破解失败!已尝试所有 {remaining_combinations:,} 种可能")
print(f"耗时: {elapsed:.2f} 秒")
print(f"{'='*50}")
return None
def smart_brute_force(zip_path, length, char_set, extract_dir, mixed_mode, selected_types, special_chars, start_password=None):
"""
智能暴力破解(优化版)
先尝试常见密码,再尝试其他组合
"""
global stop_flag, current_testing_password
print(f"\n开始智能破解...")
print(f"密码长度: {length}")
print(f"字符集: {char_set}")
if mixed_mode:
print(f"模式: 混合模式(排除纯字符组合)")
if start_password:
print(f"起始密码: {start_password}")
print("-" * 50)
attempts = 0
start_time = time.time()
# 1. 先尝试常见弱密码(仅当没有指定起始密码时)
if not start_password:
common_passwords = set()
# 纯数字常见密码
if '0' in selected_types:
common_passwords.update([
'1234', '123456', '12345678', '12345', '123', '0000', '1111', '2222',
'3333', '4444', '5555', '6666', '7777', '8888', '9999', '1212', '1122',
'0603', '2023', '0201', '8848', '1231', '123123', '111111', '0124',
'2795', '5853', '520521', '2024', '0126', '0801', '123456789', '5732',
'1314', '1212', '102074', '1115', '1717', '2025', '2026'
])
# 包含字母的常见密码
if 'a' in selected_types or 'A' in selected_types:
common_passwords.update([
'admin', 'root', 'user', 'abc', 'abcd', 'abcde', 'abcdef',
'qwer', 'qwert', 'qwerty', 'asdf', 'asdfg', 'zxcv', 'zxcvb',
'yms', 'ysm', 'bymltt', 'byhatake', 'baihehuakai', 'amtw',
'yurifans', 'HAHA', 'yuri', 'ayue'
])
# 混合常见密码
common_passwords.update([
'abc123', '123abc', 'admin123', '123admin', 'password', 'pass123',
'bctt3233', 'bycycy1', 'gn5853', 'manhun3233', 'yy123', 'abcd123'
])
# 过滤符合长度和字符集要求的常见密码
valid_common = []
for pwd in common_passwords:
if len(pwd) == length and all(c in char_set for c in pwd):
# 如果是混合模式,还要确保不是纯组合
if mixed_mode and is_pure_combo(pwd, selected_types, special_chars):
continue
valid_common.append(pwd)
if valid_common:
print(f"尝试 {len(valid_common)} 个常见密码...")
for password in valid_common:
if stop_flag:
break
attempts += 1
current_testing_password = password
print(f"\r尝试 #{attempts}: {password}", end='', flush=True)
success, _ = try_unzip(zip_path, password, extract_dir)
if success:
elapsed = time.time() - start_time
print(f"\n\n{'='*50}")
print(f"✓✓✓ 成功!密码正确!✓✓✓")
print(f"正确密码: {password}")
print(f"尝试次数: {attempts}")
print(f"耗时: {elapsed:.2f} 秒")
print(f"{'='*50}")
return password
if stop_flag:
print(f"\n\n程序已停止于常见密码阶段")
return None
print(f"\n\n常见密码未成功,开始完整暴力破解...")
# 2. 如果没有找到,再尝试所有组合
return brute_force_password(zip_path, length, char_set, extract_dir,
mixed_mode, selected_types, special_chars, start_password)
def get_start_password(length, char_set):
"""
获取起始密码
Returns:
起始密码字符串,如果为None表示从头开始
"""
print("\n" + "="*50)
print("起始密码设置说明:")
print("-" * 50)
print("您可以从指定密码开始遍历,跳过之前的密码")
print(f"当前密码长度为{length},字符集包含: {char_set}")
print("示例:")
print(f" - 数字密码: 3333, 8888, 9999")
print(f" - 字母密码: abcd, xyz, hello")
print(f" - 混合密码: abc123, 123abc")
print("-" * 50)
print("提示:")
print(" - 留空或输入0:从头开始遍历")
print(" - 输入密码:从该密码开始遍历(包含该密码)")
print(" - 所有密码必须符合长度和字符集要求")
print("="*50)
while True:
start_input = input("\n请输入起始密码(留空从头开始): ").strip()
if not start_input or start_input == '0':
return None
# 检查长度
if len(start_input) != length:
print(f"错误:密码长度必须为{length}位!")
continue
# 检查字符集
invalid_chars = [c for c in start_input if c not in char_set]
if invalid_chars:
print(f"错误:密码包含非法字符 {invalid_chars}")
print(f"允许的字符集: {char_set}")
continue
return start_input
def main():
"""主函数"""
global seven_zip_path, stop_flag
# 注册信号处理函数
signal.signal(signal.SIGINT, signal_handler)
current_dir = Path(__file__).parent
# 查找7-Zip
print("正在查找7-Zip...")
seven_zip_path = find_7zip()
if not seven_zip_path:
print("错误:找不到7-Zip!")
input("按回车键退出...")
return
print(f"✓ 找到7-Zip: {seven_zip_path}")
print("-" * 50)
# 显示当前目录下的压缩文件
zip_files = list(current_dir.glob('*.zip')) + \
list(current_dir.glob('*.rar')) + \
list(current_dir.glob('*.7z'))
if zip_files:
print("当前目录下的压缩文件:")
for f in zip_files:
print(f" - {f.name}")
else:
print("当前目录下没有找到压缩文件")
print("-" * 50)
# 输入压缩包名称
while True:
zip_name = input("\n请输入压缩包名称(如:书11.zip): ").strip()
if not zip_name:
print("请输入文件名!")
continue
zip_path = current_dir / zip_name
if not zip_path.exists():
print(f"错误:找不到文件 {zip_name}")
retry = input("是否重新输入?(y/n): ").strip().lower()
if retry != 'y':
print("程序结束")
return
continue
break
# 输入密码长度
while True:
try:
password_length = int(input("请输入密码位数(如:4): ").strip())
if password_length > 0:
break
else:
print("密码位数必须大于0!")
except ValueError:
print("请输入有效的数字!")
# 输入密码规则
print("\n" + "="*60)
print("密码规则说明:")
print("-" * 60)
print("基本规则:")
print(" - 输入 '0' 表示包含数字 0-9")
print(" - 输入 'a' 表示包含小写字母 a-z")
print(" - 输入 'A' 表示包含大写字母 A-Z")
print(" - 直接输入其他字符表示包含这些字符(如:,.!@#)")
print("-" * 60)
print("使用示例:")
print(" '0' : 纯数字")
print(" 'a' : 纯小写字母")
print(" 'A' : 纯大写字母")
print(" '0a' : 数字+小写字母(包括纯数字和纯字母)")
print(" '0aA' : 数字+大小写字母(包括纯组合)")
print(" '0aA,.!' : 数字+大小写字母+特殊字符(包括纯组合)")
print(" '-0a' : 数字+小写字母的混合(排除纯数字和纯字母)")
print(" '-0aA' : 数字+大小写字母混合(排除纯数字、纯小写、纯大写)")
print(" '-0aA,.!' : 数字+大小写字母+特殊字符混合(排除纯字符组合)")
print("="*60)
rule_input = input("\n请输入密码规则: ").strip()
if not rule_input:
rule_input = '0'
print("未输入规则,默认使用纯数字(0-9)")
# 解析规则
length, char_set, mixed_mode, selected_types, special_chars = parse_password_rule(rule_input, password_length)
# 获取起始密码
start_password = get_start_password(length, char_set)
if start_password:
print(f"将从密码 '{start_password}' 开始遍历")
# 确认信息
print("\n" + "="*50)
print("破解配置确认:")
print(f"压缩包: {zip_name}")
print(f"密码长度: {length}")
print(f"字符集: {char_set}")
print(f"字符集大小: {len(char_set)}")
print(f"密码类型: {'混合模式(排除纯字符组合)' if mixed_mode else '包含纯字符组合'}")
print(f"包含的字符类型: {', '.join(selected_types)}")
if start_password:
print(f"起始密码: {start_password}")
else:
print(f"起始密码: 从头开始")
total_combinations = len(char_set) ** length
if mixed_mode:
print(f"总组合数(混合模式): 需要实时计算(会过滤纯组合)")
print(f"原始总组合数: {total_combinations:,}")
else:
print(f"总组合数: {total_combinations:,}")
if total_combinations > 10000000 and not mixed_mode and not start_password: # 超过1千万且从头开始
print("\n⚠️ 警告:组合数较大,可能需要很长时间!")
print(f"预计时间: {total_combinations / 10000 / 60:.1f} 分钟(按每秒1万次计算)")
print("="*50)
confirm = input("\n是否开始破解?(y/n): ").strip().lower()
if confirm != 'y':
print("程序结束")
return
# 开始破解
extract_dir = current_dir # 直接解压到当前目录
print(f"\n解压目标目录: {extract_dir}")
print("提示:按 Ctrl+C 可以随时停止程序,并显示当前进度\n")
# 选择破解模式
use_smart = input("\n是否使用智能破解(先尝试常见密码)?(y/n,默认y): ").strip().lower()
if use_smart == 'n':
password = brute_force_password(zip_path, password_length, char_set, extract_dir,
mixed_mode, selected_types, special_chars, start_password)
else:
password = smart_brute_force(zip_path, password_length, char_set, extract_dir,
mixed_mode, selected_types, special_chars, start_password)
if password:
print(f"\n✓✓✓ 破解成功!密码是: {password}")
print(f"✓ 文件已解压到: {extract_dir}")
elif stop_flag:
print(f"\n程序已停止")
if current_testing_password:
print(f"最后一个测试的密码: {current_testing_password}")
else:
print(f"\n✗ 破解失败,未找到正确密码")
print("\n程序结束")
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
print("\n\n程序被用户中断")
except Exception as e:
print(f"\n程序出错: {e}")
finally:
input("\n按回车键退出...")