本文主要帮助大家建立对python的兴趣,并且总结一些我的收获或者感悟。以后可能还有其他的帖子,也可能没有(咕咕咕)。同时在我查阅暴力破解zip的各种程序或者软件时,发现大多不是很完善,可用性比较低,或者软件压根不能用= =所以写此贴。

以后或许还会写有关python的各种东东,用python写一些小工具确实很有意思。

这个程序主要涉及到简单的DFS,文件处理,自定义函数,同时包含一些简单的异常处理,元组,方面的知识,没学过也没事,基本能看懂。同时用到了zipfile模块的extractall方法。

先讲一下大致的思路,密码是由各种元素(包括数字,英文字母,符号等)组成的,那我们就需要一个文档来储存这些元素,同时配套一个函数来读取文档,使所有元素储存在列表中;其次,需要一个函数来进行有重复的排列,将元素组成密码;最后,需要一个函数来测试生成的密码是否正确。

首先是读取储存密码元素的文档,我们创建一个TXT文件,名字叫possible_password.txt,里面放上我们觉得可能的所有的数字,字母,符号。为了简便运算,我们现在里面放上123,abc。

同时我们将这个txt文件放在工程的文件夹里面

之所以把文件放在这个文件夹里,是为了方便打开,我们使用相对路径就可以打开,如果把这个txt放在桌面上,我们就要用绝对路径C:\Users\11856\Desktop\possible_password.txt。这样很复杂,而且有一个小问题,在python中(其他语言也有,包括c语言),反斜杠+n/r/f等各种元素,会传成别的意思,我们要在字符串面前加一个r,来禁止转义。

fin代表了这个文件,fin.read()会读取文件所有的内容,并返回一个字符串。(这里有关read,readline,readlines的区别很有意思,可以去查一下)。最后我们为了方便,返回一个元组,包含了一个列表和一个代表密码元素个数的length。元组很神奇,也很好用,一个括号,里面的元素用逗号隔开,就组成了元组。这样可以打破我们之前只能返回一个值的局限,一下子返回两个值,我们这样接收这两个值:

然后我们需要一个DFS算法来生成密码,这其实是一个有重复的排列问题,当然也有别的方法可以实现,但是这个问题有时候计算量很大,所以我们需要一个最高效的方法:

因为line和queue是不管递归到哪一层都要用的,所以就放在了外面,用global设置为全局变量。那一个print(temp)是一个脚手架代码。在我还没写好trypassword这个函数之前,我就靠这个检查我的有重复排列组合是否正确。大家debug除了用编译器自带的工具之外,也可以用这类脚手架代码来提高自己的debug效率。

关于DFS可以专门开一篇来讲,我现在也只用过两三次,还不精通,我找了一些比较好的资料,大家可以翻阅一下。

https://visualgo.net/zh/dfsbfs

https://blog.csdn.net/wumingkeqi/article/details/70940978

看到在DFS函数里面的那个trypassword函数了吗,那是我们要写的最后一个函数。

try except和if else 有点像,如果try的内容产生了任何错误,那么就执行except。extractall这个方法有三个参数:

path:解压缩的目录
member:需要解压缩的文件的列表
password:当zip文件有密码时需要该选项

三个参数都是可选的,由于各种原因= =python自己解压的效果并不好,比如中文名的文件解压出来,文件名就会是乱码,有的文件的内容还会丢失。那么我们主要是要知道密码,所以我们就不管path和member这两个参数了。password是一个字符串,由于python自己的字符格式是ASCII码,而加密用的是utf-8,所以我们还要转一下格式。

下面是完整代码,在破解一些简单压缩包的比较好用,但是一旦密码组合复杂起来,可能要破解个几天几夜= =……甚至直到宇宙毁灭,你也破解不出来。

专业不精,若有任何错误欢迎指正赐教。若有效率更高的方法也欢迎提出讨论。

import zipfile

def make_password_list():
fin = open('possible_password.txt')
line = list(fin.read())
length = len(line)
return (line,length)

def trypassword(password):
global zfile
try:
zfile.extractall(pwd=password.encode('utf-8'))
print("PASSWORD IS:" + password)
exit(0)
except:
pass

def DFS(had,n,m):
global line,queue
if had == n:
temp = ''
for i in range(n):
temp = temp + queue[i]
trypassword(temp)
#print(temp)
return

for index in line:
queue[had] = index
DFS(had+1,n,m)

n = int(input('请输入密码位数,若不知道,则输入0\n'))

zfile = zipfile.ZipFile("123.zip")

line,m = make_password_list()
queue = [0]*m
if n == 0:
for i in range(1,m):
DFS(0,i,m)
else:
DFS(0,n,m)




发表评论