一、前言
下载一本电子书,打开一瞧要密码,正准备给钱了事呢,发现收钱的图片挂了…上网找个破解软件嘛,很多的,可惜都要小钱钱…我要看个书就这么难吗?所以有了本文。
这种事情不是Python的强项,是最弱项。应该找C哥来干的,可C哥写起来麻烦,弄出个能用的程序,我去买本书都快递来了~(主要是手艺不行哈)所以就用 Python试试吧。小P出名的快手嘛。
二、开始
要破解首先得有密码本,这个重复造轮子是没必要滴。网上有很多同鞋已经造了很多好用的轮子,这里选了骨灰家的轮子(Linux版)。随便生成了一个密码本,共约1800多个密码,文件名为dic,其实就是个文本文件,每行一个密码。并把我正确的密码藏在文件最后用来测试软件。
from threading import Thread
from unrar import rarfile
import os
import time
file_path = './aaa.rar' # 需要破解的文件路径,这里仅对单个文件进行破解
output_path = './extract/' # 解压输出文件路径
dict_path = './dic' # 字典文件
def get_pw(dict_path): # 从字典读取文件,生成跌代器
with open(dict_path, 'r') as f:
for pwd in f:
yield pwd.strip()
上面的代码很简单,读取文件,做一个迭代器。主要考虑密码本很大的情况,这两千来个测试密码可以一次性读入内存,那种几十G的密码本可没法这么做。
下面的代码就是破解代码了:
这里要注意的是,unrar这个包要装,笔者这是ubuntu 1804
用pip3 install unrar (此命令注意权限) 就装好了,但是光这样还是不行的。会提示 Couldn’t find path to unrar library…的错误
在https://github.com/matiasb/python-unrar 项目官方文档上有答案:
请参考文档Install UnRAR library的说明。
大致就是本python项目需要官方库,如下(注意权限):
- RARLab官方下载库文件,http://www.rarlab.com/rar/unrarsrc-5.2.6.tar.gz ;(最新版5.9.1应该也是可以的,笔者这里是5.4.5)
2.tar -zxvf unrarsrc-5.2.6.tar.gz ->> cd unrar ->> sudo make lib ->> sudo make install-lib
(make不了的装g++,sudo apt install g++)
在 /usr/lib 目录下面会产生产生 libunrar.so 文件;
-
添加环境变量,编辑文件:
sudo vi /etc/profile
在最后面添上:export UNRAR_LIB_PATH=/usr/lib/libunrar.so
-
保存退出后,运行:
source /etc/profile
-
如果还不行呢:则在~目录下的.bash_profile中配置环境变量,如上面所示一致。还不行就重启一下,保你OK。
def dec_pwd(file_path, output_path, pwd):
# 传入被解压的文件路径,生成待解压文件对象
file = rarfile.RarFile(file_path)
# 输出解压后的文件路径
out_put_file_path = './extract/{}'.format(file.namelist()[0])
# 尝试解压文件
file.extractall(path=output_path, pwd=pwd)
try:
# 删除解压后的第一个文件,用来测试是否成功
os.remove(out_put_file_path)
# 上一句被执行,说明当前密码有效,并告知
print('Find password is "{}"'.format(pwd))
end = time.time()
print('程序耗时{}'.format(end - start))
return True
except Exception as e:
# 如果删除文件出错
pass
if __name__ == '__main__':
pwds = get_pw(dict_path)
start = time.time()
while True: # 单线程版本 运行时好看 没有错误提示
pwd = pwds.__next__()
print(pwd)
try:
dec_pwd(file_path, output_path, pwd=pwd)
except:
continue
end = time.time()
print('程序耗时{}'.format(end - start))
以下提供多线程版本:最后的while True:
这里开始替换就行
while True: # 多线程版本,实测比下面的单线程版快45% 运行时会有很多异常提示,不影响使用
try:
pwd = pwds.__next__()
th = Thread(target=dec_pwd, args=(file_path, output_path, pwd))
th.start()
except:
pass
三、总结
代码还是比较简单的,结合注释我想是比较容易看明白的。这是本人实际测试的,在写代码前也想着去找找现成代码,结果大多都不靠谱!而且无数文章全长一样,当真是
天下文章全靠抄,靠不靠谱都要抄…
在笔者的I5,8G,固态硬盘,Ubuntu1804的ThinkPad笔记本上,单线程版解出密码用时363秒左右,平均每秒才约5个…多线程版解出密码用时190秒,平均每秒也不到10个…
最后老实地掏钱去买实体书吧!本程序适用于你自己设置的密码却又忘记了但记得个大概的情况,也可以用来试试弱密码。只要字典做得好,还是有点机会的!
附多线程测试图片