在日常工作生活中,可能会遇到压缩文件后忘记解压密码的情况,也许你大概知道密码构成及位数,一个一个手动输入的试密码显然很麻烦,那么利用程序自动测试密码就非常方便
zip密码字典破解
1,新建一个zip压缩文件(破解测试.zip),设置密码为123456或987654
2,创建一个txt文件(密码字典.txt),保存可能的密码
from itertools import permutations
def password_txt():
filename = r'E:\测试\密码字典.txt'
with open(filename, 'w', encoding='utf-8') as file:
# 写入数字10选6所有排列151200种
str_n = '0123456789'
for i in permutations(str_n, 6):
file.write('{}\n'.format(''.join(i)))
print('所有排列写入完成')
if __name__ == '__main__':
password_txt()
3,编写python破解代码
import zipfile
from threading import Thread
from time import time
i = 0
pwd_return = None # 多线程返回值,正确的密码
def extractfile(zfile, password):
# 密码破解函数
try:
zfile.extractall(pwd=bytes(password, 'utf8'))
print('文件解压密码为: ', password)
global pwd_return
pwd_return = password
return True
except:
return False
# 以下为测试使用
#global i
#i = i + 1
#print('密码错误第{}次\n'.format(i))
def extract1():
# 直接破解
start_time = time()
zip_file = r'E:\测试\破解测试.zip'
pass_file = r'E:\测试\密码字典.txt'
zfile = zipfile.ZipFile(zip_file)
pfile = open(pass_file)
for line in pfile.readlines(): # 按行读取密码
pwd = line.strip('\n')
if extractfile(zfile, pwd): # 直接调用函数,非多线程
print('密码{},用时{:.2f}秒'.format(pwd, time()-start_time))
break # 跳过剩余密码
def extract2():
# 多线程破解
start_time = time()
zip_file = r'E:\测试\破解测试.zip'
pass_file = r'E:\测试\密码字典.txt'
zfile = zipfile.ZipFile(zip_file)
pfile = open(pass_file)
for line in pfile.readlines():
pwd = line.strip('\n')
t = Thread(target=extractfile, args=(zfile, pwd)) # 运用子进程加快运行
t.start()
if pwd_return != None:
break # 跳过剩余密码
print('密码{},用时{:.2f}秒'.format(pwd_return, time()-start_time))
if __name__ == '__main__':
extract1()
4,测试结果
测试数字10选6所有排列151200种密码
密码 | extract1()耗时(秒) | extract2()耗时(秒) |
---|---|---|
第17047行密码123456 | 1.76 | 3.2 |
第151200行密码987654 | 10.86 | 28.76 |
可以发现多线程并没有什么作用;测试过程中还发现,在不使用多线程时CPU占用 <1%,而使用时CPU占用在15%-20%
报错处理
可能存在代码无法正确运行,报错 PermissionError: [Errno 13] Permission denied 的情况,这是由于使用正确的密码破解文件时,会在python.exe所在文件夹生成一个解压文件,而如果该文件夹属性是只读则会无法写入而导致运行错误。
解决方法:文件夹属性修改取消只读,如果无法修改,则可以在文件夹权限中修改为完全控制,如图
zip密码排列破解
创建密码字典也挺麻烦的,直接使用python排列组合itertools模块排列功能
同样调用上面的extractfile()函数
import zipfile
from time import time
from itertools import permutations # 标准库排列迭代器
from math import factorial # 阶乘
def extract_permut():
# 排列破解
start_time = time()
zip_file = r'E:\测试\破解测试98765432.zip'
str_n = '0123456789' # 排列元素
m = 8 # 抽取元素
piece = 10*10000 # 分段
num = 19 # 第num个分段[(num-1)*piece, num*piece],为0则查找全部
zfile = zipfile.ZipFile(zip_file)
count = 0
count_max = int(factorial(len(str_n)) / factorial(len(str_n)-m))
count_s = (num-1)*piece if num > 0 else 0
count_e = num*piece if num > 0 else count_max
if count_s > count_max:
print('超出范围,最大排列数为{}'.format(count_max))
return
for i in permutations(str_n, m):
if count >= count_s and count <= count_e:
pwd = ''.join(i)
if extractfile(zfile, pwd):
print('密码{},用时{:.2f}秒'.format(pwd, time()-start_time))
break
count = count + 1
if pwd_return == None:
print('密码排列{}-{}错误,用时{:.2f}秒'.format(count_s, count_e, time()-start_time))
if __name__ == '__main__':
extract_permut()
破解密码测试
密码排列 | 10选6共151200种排列 | 10选8共1814400种排列 |
---|---|---|
耗时(秒) | 15.66 | 190.68 |
破解速度近10000个/秒,速度还是比较快的
Excel密码排列破解
from time import time
from itertools import permutations
from win32com.client import Dispatch
excel = Dispatch('Excel.Application')
excel.Application.Visible = 0 # 后台运行,不显示界面
excel.Application.DisplayAlerts = 0 # 不显示警告信息
def excel_extract(filename, password):
# excel密码破解函数
try:
wb = excel.Workbooks.Open(Filename=filename, UpdateLinks=False, ReadOnly=False, Format=None, Password=password, WriteResPassword=password)
print('excel打开密码为: ', password)
wb.Close()
excel.Application.Quit()
return True
except:
return False
def excel_password():
# 排列破解
start_time = time()
xlsx = r'E:\测试\密码cba321.xlsx'
str_n = '123abc' # 排列元素
m = 6 # 抽取元素
for i in permutations(str_n, m):
pwd = ''.join(i)
if excel_extract(xlsx, pwd):
print('密码{},用时{:.2f}秒'.format(pwd, time()-start_time))
break
if __name__ == '__main__':
excel_password()
测试结果
速度很一般,6选6共720种排列,用时80.85秒,较VBA破解方式稍慢
《Excel·VBA破解密码》