【計劃執行報告】Day11 04-10 zip文件密碼破解
Day11 04-10 zip文件密碼破解
今天:
- 計劃執行的第11天
- 離藍橋杯模擬賽還有8天
1. 今日動態
-
《ML中的數學》已完成第四章、第五章(5.1-5.5)
複習指引:- 隱函數的意義以及隱函數求導法
- 懸掛模型結論:把一個物體通過兩根繩子拴在兩個固定的釘子上,靜止時兩根繩子分別與豎直方向的夾角是相等的
- 幾個不定積分的推導:
- 定積分第二定理
-
今天設計了雙向鏈表,但卻因爲兩個超低級錯誤導致多花了1h30min;在此之前趁間歇時間額外刷了3道Leetcode題
-
今天嘗試破解了固定模板的zip壓縮密碼(C/C++以及Python3聯合實現)
2. 計劃執行報告
2.1 近期計劃(03-31-04-12)(更新)
-
《機器學習中的數學》高等數學篇
-
完成專業課的作業(流體機械能轉化、生物質能,新能源熱利用);
-
備戰藍橋杯,爲此:①利用中午1h左右的時間補充數據結構知識(優先Leetcode“探索”模塊);②C/C++語法知識;③常見數據結構的構造與基本操作實現;④必要的練習與練題總結(比如時長1:30虛擬競賽與“覆盤”)
2.2 今日計劃表
2.3實際時間分配
- 昨天睡晚了,睡眠有點不足,好在不是很累;
3. 帶有固定密碼模板的Zip壓縮密碼的破解
今日很多任務都提前完成了,因此我利用多處來的時間嘗試通過自己編程來破解本地磁盤上的zip文件,通過1個小時的編程以及1個半小時的程序運行,最終把密碼破解成功了(一共13位)。爲了更方便說明,我把這個實際問題概括成以下程序問題:
【問題描述】假如你有一個待破解的zip壓縮文件,你唯一知道的是它的密碼形式爲“H*E*L*L*O”(共9位),其中的*號爲0-9的數字,比如可能的密碼:H1E2L1L4L7O等等。現在要求你編寫程序,找出zip文件的密碼。
【我的思路】首先把所有可能的這種形式的密碼按行寫入到一個文本文件中保存,以它作爲破解的密碼字典,然後一個個與Zip文件的密碼進行比對,直到能成功打開時,輸出改密碼即可。
我不太熟悉Python3的文件操作,因此使用了C++先寫了個字典生成代碼(genDict.cpp),然後通過Python3的代碼調用這個字典並進行與zip目標文件的密碼比對(Pyhton實現參考鏈接),實現如下:
【genDict.cpp】
#include<iostream>
#include<fstream>
#include<string>
#include<vector>
#include<sstream>
#include<ctime>
#include<windows.h>
using namespace std;
#define ERROR -1
#define OK 1
string crossCat(string str1,string str2){//str1長於str2
string ret;
if(str1.length()&&str2.length()){
ret.append(str1,0,1);
for(int i=0;i<str2.length();i++){
ret.append(str2,i,1);
ret.append(str1,i+1,1);
}
//cout<<ret<<endl;
}
return ret;
}
//把不足位的數前面補零,比如四位數0000 0001等等
string appendZero(string str,int num_size){
int p=num_size-str.length();
if(p<0){
cout<<"reform() args error!"<<endl;
return NULL;
}
else if(p==0) //不用補位
return str;
string s="";
for(int i=0;i<p;i++){
s.append("0");
}
s.append(str);
return s;
}
int max_range(int num_size){//num_size 待求數的總位數
int ans=0;
for(int i=0;i<num_size;i++){
ans*=10;
ans+=9;
}
return ans;
}
vector<string> genDict(string mod){
vector<string> v;
int size=mod.length()-1;
int max=max_range(size);
for(int i=0;i<=max;i++){
stringstream ss;
string str="";
ss.clear();
ss<<i;
ss>>str;
str=appendZero(str,size);
v.push_back(crossCat(mod,str));
//cout<<v.back()<<endl;
}
return v;
}
int saveDict_TXT(string path,string mod){
vector<string> v=genDict(mod);
stringstream ss;
char ch_path[100];
ss<<path;
ss>>ch_path;
cout<<ch_path<<endl;
ofstream outfile(ch_path,ios::trunc);
if(!outfile.is_open()){
cout<<"error"<<endl;
return ERROR;
}
for(int i=0;i<v.size();i++){
outfile<<v[i]<<endl;
}
outfile.close();
return OK;
}
int main(){
long long a=clock();
cout<<"本程序只適合諸如\'a*b*c*d*2*4\'類型的密碼模板:"<<endl;
cout<<"其中的\'*\'是待求位(數字),使用時只需輸入\'abcd24\'即可"<<endl;
cout<<"字典保存在程序所在文件夾中"<<endl;
cout<<"請輸入密碼模板:";
string mod;
cin>>mod;
string savePath="Dict.txt";
//crossCat("ShengGe","111111"); //OK
//genDict("ShengGe"); //OK
saveDict_TXT(savePath,mod);
long long b=clock();
cout<<"總共用時:"<<(b-a)*1.0/CLOCKS_PER_SEC<<"s"<<endl;
system("pause");
return 0;
}
【ZipCrack.py】
import zipfile
global i # 記錄總次數
i = 0
global flag # 作爲查找結束的標誌
flag = 0
def extractfile(zfile, password):
try:
zfile.extractall(pwd = bytes(password, "utf8" ))
print("查找成功!!文件解壓密碼爲: ", password)
return 1
except:
global i
i = i + 1
print("密碼錯誤第%s次" % i)
return 0
def main():
zfile = zipfile.ZipFile(r'E:\密碼破解\dark_fantasy.zip') # 待破解文件
dictfile = open(r'E:\密碼破解\Dict.txt') # 密碼字典
flag = 0
for line in dictfile.readlines():
password = line.strip('\n') # 除去換行符
flag = extractfile(zfile, password)
if flag == 1:
break
if __name__ == "__main__":
main()
【實驗步驟與結果】
- 首先運行genDict.exe:
- 運行成功後生成Dict文件
- 然後運行在同一目錄下的ZipCrack.py,等待時間取決於密碼的複雜度(這裏只有四位未知數字,時間2min左右即可)
Python IDLE下的運行結果:
命令行下的運行結果:
用命令行時的運行速度明顯快於IDLE,原因尚不知道。
【明日計劃】
我很喜歡的一個電影是《帝企鵝日記》,企鵝是一種很可愛的動物,在他身上集結了愛、勇氣和冒險的精神。
——馬化騰 (這難道就是選擇企鵝爲logo的原因?)