一、前言
下載一本電子書,打開一瞧要密碼,正準備給錢了事呢,發現收錢的圖片掛了…上網找個破解軟件嘛,很多的,可惜都要小錢錢…我要看個書就這麼難嗎?所以有了本文。
這種事情不是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個…
最後老實地掏錢去買實體書吧!本程序適用於你自己設置的密碼卻又忘記了但記得個大概的情況,也可以用來試試弱密碼。只要字典做得好,還是有點機會的!
附多線程測試圖片