从朋友那里搞来一些好东西,连续下载了好几个解压密码都是错误的,问朋友他也不知道怎么回事,我就怀疑这些密码怕早是过期了,但是好在原密码的规则不是很复杂。就想到写了这个程序来破解。

先按照规则跑一个密码本出来,不是很大,六位数的随机密码有一百万条。
import itertools
all_pwds = [''.join(map(str, p)) for p in itertools.product(range(10), repeat=6)]
with open('pwd.txt', 'w') as file:
for pwd in all_pwds:
file.write(pwd + '\n')

为了测试代码将压缩包的密码设置为最后一个密码999999用以调试代码达到最佳速度。

破解部分代码也是优化重构成了好几个版本。

先来看看最快的版本,,跑完一百万个密码的时间是13秒左右。
import zipfile
import time
from multiprocessing import Pool
def test_zip(zip_path):
try:
with zipfile.ZipFile(zip_path) as zf:
if zf.testzip() is None:
return False
else:
return True
except Exception as e:
return True
def find_pwd(pwds, zipPack_path):
with zipfile.ZipFile(zipPack_path) as zf:
for pwd in pwds:
try:
zf.extractall(pwd=pwd.encode())
return pwd
except Exception as e:
pass
return None
def calculate_chunk_size(pwd_dict):
try:
with open(pwd_dict, "r", encoding="utf-8") as f:
pwds = f.read().splitlines()
num_pwds = len(pwds)
if num_pwds < 100000:
return num_pwds
else:
return num_pwds // 10
except Exception as e:
print(f"打开密码字典文件失败: {e}")
return 100000
def main():
while True:
zip_path = input("zip_path: ")
if test_zip(zip_path):
break
else:
print("zip_path error:")
pwd_dict_path = None
while pwd_dict_path is None:
pwd_dict_path = input("pwd_dict_path: ")
try:
with open(pwd_dict_path, "r", encoding="utf-8") as f:
pwds = f.read().splitlines()
except Exception as e:
print(e)
pwd_dict_path = None
start_time = time.time()
found_pwd = False
chunk_size = calculate_chunk_size(pwd_dict_path)
with Pool(processes=5) as pool:
pwd_chunks = [pwds[i:i + chunk_size] for i in range(0, len(pwds), chunk_size)]
results = [pool.apply_async(find_pwd, (chunk, zip_path)) for chunk in pwd_chunks]
for result in results:
if result.get() is not None:
found_pwd = True
break
if found_pwd:
print(f"OK!!!,TRUE PWD:{result.get()} TIME: {time.time() - start_time:.1f} S")
return
print("Fuck!!!")
return None
if __name__ == "__main__":
main()
input("任意键退出...")

再来看个站在用户角度(对外友好)的版本,就是为了让人知道,破解过程中,程序还是在运行的而不是卡死了。
import zipfile
import time
import threading
def test_zip(zip_path):
try:
with zipfile.ZipFile(zip_path) as zf:
if zf.testzip() is None:
print("该压缩包未被加密")
return False
else:
return True
except zipfile.BadZipFile:
print("指定的文件不是一个有效的zip压缩文件")
return True
except FileNotFoundError:
print("没有这个文件或目录")
except Exception as e:
return True
def find_pwd(pwds, zips_path, result):
with zipfile.ZipFile(zips_path) as zf:
for pwd in pwds:
try:
zf.extractall(pwd=pwd.encode())
result.append(pwd)
return
except Exception as e:
pass
def calculate_chunk_size(pwd_dict):
try:
with open(pwd_dict, "r", encoding="utf-8") as f:
pwds = f.read().splitlines()
num_pwds = len(pwds)
if num_pwds < 100000:
return num_pwds
else:
return num_pwds // 10
except Exception as e:
print(f"打开密码字典文件失败: {e}")
return 100000
def main():
while True:
zip_path = input("请输入目标压缩包路径: ")
if test_zip(zip_path):
break
else:
print("文件不存在,请重新输入正确的压缩包路径。")
pwd_dict_path = None
while pwd_dict_path is None:
pwd_dict_path = input("请输入密码字典文件路径: ")
try:
with open(pwd_dict_path, "r", encoding="utf-8") as f:
pwds = f.read().splitlines()
except FileNotFoundError:
print("没有这个文件或目录")
pwd_dict_path = None
except UnicodeDecodeError:
print("密码本不是utf-8编码的文本文件")
pwd_dict_path = None
except PermissionError:
print("没有权限访问该文件或目录")
pwd_dict_path = None
except IsADirectoryError:
print("指定的路径是一个目录而不是文件")
pwd_dict_path = None
except OSError:
print("指定的路径无效")
pwd_dict_path = None
except Exception as e:
print(f"打开密码字典文件失败: {e}")
pwd_dict_path = None
start_time = time.time()
found_pwd = False
chunk_size = calculate_chunk_size(pwd_dict_path)
result = []
def loading():
print("破解中", end="")
while not found_pwd:
for i in range(3):
print(".", end='', flush=True)
time.sleep(0.2)
print("\b \b" * 3, end='', flush=True)
t = threading.Thread(target=loading)
t.start()
pwd_chunks = [pwds[i:i + chunk_size] for i in range(0, len(pwds), chunk_size)]
for chunk in pwd_chunks:
find_pwd(chunk, zip_path, result)
if result:
found_pwd = True
break
t.join()
if found_pwd:
print(f"密码破解成功,TRUE PWD:{result[0]} 用时 {time.time() - start_time:.2f} 秒")
else:
print("密码破解失败,尝试其它密码本")
if __name__ == "__main__":
main()
input("任意键退出...")

这个版本就只是带了一个破解中loading,结果时间就是翻了一倍多!?好吧!我不会写更加高效的loading[苦笑],我自己会看任务管理器知道程序是否还在运行,但是对外还是要写一个loading才行。
我就尝试换一个loading方式,结果也是不如意的,仅仅快了几秒钟:
def loading():
symbols = "|/-"
count = 0
while not found_pwd:
symbol = symbols[count % len(symbols)]
print(symbol, end='', flush=True)
count += 1
time.sleep(0.1)
print("\b", end='', flush=True)
t = threading.Thread(target=loading)
t.start()

最后来看看我的第一版,真的速度感人。
import zipfile
import time
def test_zip(zip_path):
try:
with zipfile.ZipFile(zip_path) as zf:
if zf.testzip() is None:
print("压缩包未被加密")
return False
else:
return True
except zipfile.BadZipFile:
print("指定的文件不是有效的 zip 存档")
return True
except Exception as e:
return True
def find_pwd(pwds, zips_path):
for pwd in pwds:
with zipfile.ZipFile(zips_path) as zf:
try:
zf.extractall(pwd=pwd.encode())
return pwd
except Exception as e:
pass
return None
def main():
start_time = time.time()
while True:
zip_path = input("输入目标zip的路径: ")
if test_zip(zip_path):
break
else:
print("文件不存在,请输入正确的压缩包路径:")
while True:
pwd_dict_path = input("输入密码字典文件路径: ")
try:
with open(pwd_dict_path, "r", encoding="utf-8") as f:
pwds = f.read().splitlines()
break
except FileNotFoundError:
print("指定的文件或目录不存在。")
except Exception as e:
print(f"无法打开密码词典文件: {e}")
found_pwd = False
chunk_size = len(pwds) // 10
pwd_chunks = [pwds[i:i + chunk_size] for i in range(0, len(pwds), chunk_size)]
for chunk in pwd_chunks:
result = find_pwd(chunk, zip_path)
if result is not None:
found_pwd = True
break
if found_pwd:
total_time = time.time() - start_time
print(f"\nOK!!!, TRUE PWD: {result} Time: {total_time:.2f} S")
else:
print("\nFUCK!!!")
if __name__ == "__main__":
main()

哎,算了,虽然我的编码水平很差,但又不是不能用,写出来就当看个乐子了,所以不喜勿喷哈。
如果真有需要的朋友就推荐使用ziperello这个工具,纯数字密码破解还是很快的。