前言
本文繼續記錄學習下 Python 的有趣應用:藉助 Python 腳本暴力破解 ZIP 加密文件的密碼。雖然有相關的工具 ARCHPR 可實現 RAR、ZIP 等壓縮加密文件的可視化暴力破解,但是主要是為了學習 Python 編程應用。
Python語法
既然本意是學習 Python 編程,那自然是要對本實戰應用場景的編碼過程遇到的相關語法知識進行學習。
在此先推薦一個 Python 語法的官方站點:Python官方中文文檔,支持下載到本地。
自定義迭代器
迭代是 Python 最強大的功能之一,是訪問集合元素的一種方式。迭代器是一個可以記住遍歷的位置的對象,迭代器對象從集合的第一個元素開始訪問,直到所有的元素被訪問完結束。迭代器只能往前不會後退,迭代器有兩個基本的方法:iter() 和 next()。
1、迭代器對象可以使用常規 for 語句進行遍歷:

2、也可以使用 next() 函數:

3、Python 支持編寫 class 來自定義迭代器,如何自定義一個迭代器:
- 在自定義的類中添加了__iter__魔法方法可取得迭代器;
- 在自定義的類中通過__next__魔法方法指出所有的數據。
來看看一個簡單的自定義可迭代的類示例:

代碼運行效果:

Python多線程
線程是 CPU 分配資源的基本單位,但一個程序開始運行後這個程序就變成了一個進程,而一個進程相當於一個或者多個線程。當沒有多線程編程時,一個進程也是一個主線程,但有多線程編程時,一個進程包含多個線程,包括主線程。使用線程可以實現程序的並發,Python 多線程快速入門可參見:python3 多線程編程。
Python3 線程中常用的兩個模塊為:
- (1)_thread;
- (2)threading (推薦使用)
其中 thread 模塊已被廢棄,用戶可以使用 threading 模塊代替。所以在 Python3 中不能再使用 「thread」 模塊,為了兼容性,Python3 將 thread 重命名為 「_thread」。
1、函數創建多線程
Python3 中提供了一個內置模塊threading.Thread,可以很方便的創建多線程,threading.Thread()一般接收2個參數:
1)線程函數名:要放置線程讓其後台執行的函數,有用戶自己定義,主要不要加();
2)線程函數的參數:線程函數名所需的參數,以 tuple 元組的形式傳入,如果不需要參數,可以不指定。
下面來看看一個簡單的多線程示例:

代碼運行效果:

2、類創建多線程
首先,自定義一個類,對這個自定義的類有兩個要求:
- 1)必須繼承 threading.Thread 這個父類;
- 2)必須重寫 run() 這個方法:run() 方法相當於第一種方法中的線程函數,可以寫自己需要的業務邏輯代碼,在start()後將會調用。
來看看示例代碼:

3、 join() 方法
多線程中 join() 作用是調用 join() 的線程阻塞直到某一線程結束才繼續執行。來看看示例代碼:

代碼運行效果:

4、線程的同步——鎖
當一個進程擁有多個線程之後,如果他們各做各的任務互沒有關係還行,但既然屬於同一個進程,他們之間總是具有一定關係的。比如多個線程都要對某個數據進行修改,則可能會出現不可預料的結果。為保證操作正確,就需要引入鎖來進行線程間的同步。
Python3 中的 threading 模塊提供了 RLock 鎖(可重入鎖):
- 對於某一時間只能讓一個線程操作的語句放到 RLock 的 acquire 方法 和 release 方法之間;
- 即 acquire() 函數相當於給 RLock 鎖 上鎖,而 release() 函數相當於解鎖。
來看看一個簡單的演示案例:

代碼運行效果:

5、多線程函數小結:

Python腳本
下面將從單線程、多線程兩種角度實現 ZIP 加密文件的密碼爆破。
單線程數字爆破
先來生成一個用數字密碼(「101」)加密的 ZIP 壓縮文件 password.zip,壓縮文件為圖片 pasword.png(注意勾選 「ZIP 傳統加密」 的選項,後面的代碼不支持 WinRAR 新式的默認加密方式),如下圖所示:

爆破密碼的腳本也相對簡單,直接上代碼:


以上代碼沒什麼需要特別解釋的,簡單補充兩點:
- 需要注意的是在爆破過程需要使用異常處理機制避免密碼錯誤時程序直接終止;
- 對於 zipfile 庫的用法有疑問請參見官方文檔:ZipFile數據壓縮與存檔。
下面直接來看看 Pycharm 中運行腳本的效果:

單線程字元爆破
先來看看腳本:


將 password.png 重新壓縮並將解壓密碼設置為 「ab12」 數字與字母組合的字元串,上述利用自定義迭代器生成的字元組合範圍太廣了,爆破起來可能跑到天荒地老……故演示此代碼時我依據已知的密碼對代碼做了如下更改:
- 設置縮小字元範圍:letters = ‘abcd0123456789’;
- 設置縮小遍歷的字元串長度:for password in MyIterator(3, 4)。
來看看腳本運行效果,還足足跑了 78 秒之久:

多線程字典爆破
直接上腳本:


代碼運行效果:

總結
個人感覺最後的多線程腳本實際上意義不大,僅供簡單學習多線程使用……因為此程序中對每個密碼的嘗試都單開了一個線程、而嘗試密碼是否正常的邏輯函數 extractfile() 又十分簡單,沒有必要單開一個線程來浪費資源,除非說處理的邏輯函數 extractfile() 執行了十分耗時的操作(比如需要下載文件、或者說每次執行 extractfile() 函數都對一個單獨的大型字典進行爆破等)。
原創文章,作者:投稿專員,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/225756.html
微信掃一掃
支付寶掃一掃