Python 函数和类

2019 年 7 月 16 日 计算机与网络安全

一次性付费进群,长期免费索取教程,没有付费教程。

教程列表见微信公众号底部菜单

进微信群回复公众号:微信群;QQ群:460500587

微信公众号:计算机与网络安全

ID:Computer-network

CC++Java、Ruby、Perl、Lisp等编程语言之中,所有程序都是由函数(有的编程语言叫做过程、方法什么的)和类组成的。可以说任何程序里面包含的不是函数就是类,Python当然也不例外。


1、函数


In Python Everything Is A Function,在Python程序中,所有的一切都是函数。这是典型的C语言写法,把所需的功能都写成一个个的函数,然后由函数调用函数。以此类推,最终完成整个程序的功能。


不管用什么工具,暴力破解都少不了一个合适的字典文件(此字典非彼字典,这里的字典指的是一个包含密码的文件,也就是一个密码集,而不是Python的变量类型)。当然网上有很多的密码字典可供下载,但它们要么太大,遍历一次需要太多的时间,要么没有针对性,根本就不包含所需的密码。如果已知道一些可能是密码的字符串,完全可以根据已知条件用程序编写有针对性的字典出来,这样会节省很多时间。


现在来编写一个简单的程序mkPassFileFunction.py。mkPassFileFunction.py用于创建一个有针对性的专用密码字典。打开putty连接到Linux,执行命令:


cd code/crawler

vi mkPassFileFunction.py


mkPassFileFunction.py的代码如下:


1    #!/usr/bin/env python3

2    #-*- coding: utf-8 -*-

3    __author__ = 'hstking hst_king@hotmail.com'

4

5    import os

6    import platform

7    import itertools

8    import time

9

10     def main():

11     '''主程序 '''

12     global rawList #原始数据列表

13     rawList = []

14     global denyList #非法单词列表

15     denyList = [' ','','@']

16     global pwList #最终的密码列表

17     pwList = []

18     global minLen #密码的最小长度

19     minLen = 6

20     global maxLen #密码的最大长度

21     maxLen = 16

22     global timeout

23     timeout = 3

24     global flag

25     flag = 0

26     run = {

27    '0':exit,

28    '1':getRawList,

29    '2':addDenyList,

30    '3':clearRawList,

31    '4':setRawList,

32    '5':modifyPasswordLen,

33    '6':createPasswordList,

34    '7':showPassword,

35    '8':createPasswordFile

36     }

37

38     while True:

39         mainMenu()

40         op = input('输入选项:')

41         if op in map(str,range(len(run))):

42             run.get(op)()

43         else:

44             tipMainMenuInputError()

45             continue

46

47     def mainMenu():

48     '''主菜单 '''

49     global denyList

50     global rawList

51     global pwList

52     global flag

53     clear()

54     print('||'),

55     print('='*40),

56     print('||')

57     print('|| 0:退出程序')

58     print('|| 1:输入密码原始字符串')

59     print('|| 2:添加非法字符到列表')

60     print('|| 3:清空原始密码列表')

61     print('|| 4:整理原始密码列表')

62     print('|| 5:改变默认密码长度(%d-%d)' %(minLen,maxLen))

63     print('|| 6:创建密码列表')

64     print('|| 7:显示所有密码')

65     print('|| 8:创建字典文件')

66     print('||'),

67     print('='*40),

68     print('||')

69     print('当前非法字符为:%s' %denyList)

70     print('当前原始密码元素为:%s' %rawList)

71     print('共有密码%d个' %len(pwList))

72     if flag:

73         print("已在当前目录创建密码文件dic.txt")

74     else:

75         print("尚未创建密码文件")

76

77    def clear():

78     '''清屏函数 '''

79     OS = platform.system()

80     if (OS == u'Windows'):

81         os.system('cls')

82     else:

83         os.system('clear')

84

85     def tipMainMenuInputError():

86     '''错误提示 '''

87     clear()

88     print("只能输入0-7的整数,等待%d秒后重新输入" %timeout)

89     time.sleep(timeout)

90

91     def getRawList():

92     '''获取原始数据列表 '''

93     clear()

94     global denyList

95     global rawList

96     print("输入回车后直接退出")

97     print("当前原始密码列表为:%s" %rawList)

98     st = None

99     while not st == '':

100         st = input("请输入密码元素字符串:")

101         if st in denyList:

102             print("这个字符串是预先设定的非法字符串")

103             continue

104         else:

105             rawList.append(st)

106             clear()

107             print("输入回车后直接退出")

108             print("当前原始密码列表为:%s" %rawList)

109

110     def addDenyList():

111     '''添加非法词 '''

112     clear()

113     global denyList

114     print("输入回车后直接退出")

115     print("当前非法字符为:%s" %denyList)

116     st = None

117     while not st == '':

118         st = input("请输入需要添加的非法字符串:")

119         denyList.append(st)

120         clear()

121         print("输入回车后直接退出")

122         print("当前非法字符列表为:%s" %denyList)

123

124     def clearRawList():

125     '''清空原始数据列表 '''

126     global rawList

127     rawList = []

128

129     def setRawList():

130     '''整理原始数据列表 '''

131     global rawList

132     global denyList

133     a = set(rawList)

134     b = set(denyList)

135     rawList = []

136     for str in set(a - b):

137         rawList.append(str)

138

139     def modifyPasswordLen():

140     '''修改默认密码的长度 '''

141     clear()

142     global maxLen

143     global minLen

144     while True:

145         print("当前密码长度为%d-%d" %(minLen,maxLen))

146         min = input("请输入密码最小长度:")

147         max = input("请输入密码最大长度:")

148         try:

149             minLen = int(min)

150             maxLen = int(max)

151         except ValueError:

152             print("密码长度只能输入数字[6-18]")

153             break

154         if minLen not in range(6,19) or  maxLen not in range(6,19):

155             print("密码长度只能输入数字[6-18]")

156             minLen = 6

157             maxLen = 16

158             continue

159         if minLen == maxLen:

160             res = input("确定将密码长度设定为%d吗?(Yy/Nn)" %minLen)

161             if res not in list('yYnN'):

162                 print("输入错误,请重新输入")

163                 continue

164             elif res in list('yY'):

165                 print("好吧,你确定就好")

166                 break

167             else:

168                 print("给个机会,改一下吧")

169                 continue

170         elif minLen > maxLen:

171             print("最小长度比最大长度还大,可能吗?请重新输入")

172             minLen = 6

173             maxLen = 16

174             continue

175         else:

176             print("设置完毕,等待%d秒后回主菜单" %timeout)

177             time.sleep(timeout)

178             break

179

180     def createPasswordList():

181     '''创建密码列表 '''

182     global rawList

183     global pwList

184     global maxLen

185     global minLen

186     titleList = []

187     swapcaseList = []

188     for st in rawList:

189         swapcaseList.append(st.swapcase())

190         titleList.append(st.title())

191     sub1 = []

192     sub2 = []

193     for st in set(rawList + titleList + swapcaseList):

194         sub1.append(st)

195     for i in range(2,len(sub1) + 1):

196         sub2 += list(itertools.permutations(sub1,i))

197     for tup in sub2:

198         PW = ''

199         for subPW in tup:

200             PW += subPW

201         if len(PW) in range(minLen,maxLen + 1):

202             pwList.append(PW)

203         else:

204             pass

205

206     def showPassword():

207     '''显示创建的密码 '''

208     global pwList

209     global timeout

210     for i in range(len(pwList)):

211         if i%4 == 0:

212             print("%s\n" %pwList[i])

213         else:

214             print("%s\t" %pwList[i]),

215     print('\n')

216     print("显示%d秒,回到主菜单" %timeout)

217     time.sleep(timeout)

218

219     def createPasswordFile():

220     '''创建密码字典文件 '''

221     global flag

222     global pwList

223     print("当前目录下创建字典文件:dic.txt")

224     time.sleep(timeout)

225     with open('./dic.txt','w+') as fp:

226         for PW in pwList:

227             fp.write(PW)

228             fp.write('\n')

229     flag = 1

230

231

232     if __name__ == '__main__':

233     main()


按Esc键,进入命令模式后输入:wq,保存mkPassFileFunction.py。mkPassFileFunction.py稍微复杂一点点,它的作用就是根据用户输入的“密码元素”来创建一个字典列表。该脚本将输入的元素根据一定的规则修改、添加后当作新元素添加到元素列表中去。最后将元素列表排列组合得到字典列表。执行命令:


python3 mkPassFileFunction.py


得到的结果如图1所示。

图1  运行mkPassFileFunction.py

C语言的写法好处就是关系简单明了,函数调用一目了然。如果调用的函数过多,就难免有些混乱了。简单功能的程序还无妨,稍大一点项目就有些吃力了。


不要添加太多的“密码元素”,这个程序只是利用了Python 3的模块,没有优化算法。如果输入的“密码元素”超过了20个,那么创建密码字典的时间会非常长。

2、类


既然有了In Python Everything Is A Function,当然会有In Python Everything Is A Class。这种C++的写法就是把所有相似的功能都封装到一个类里。最理想的情况是一个程序只有一个主程序,然后在主程序里实例化类。


还是以编写密码字典为例,将mkPassFileFunction.py改编成mkPassFileClass.py。打开Putty连接到Linux,执行命令:


cd code/crawler

vi mkPassFileClass.py


mkPassFileClass.py的代码如下:


1    #!/usr/bin/env python3

2    #-*- coding: utf-8 -*-

3    __author__ = 'hstking hst_king@hotmail.com'

4

5    import os

6    import platform

7    import itertools

8    import time

9

10     class MakePassword(object):

11     def __init__(self):

12         self.rawList = []

13         self.denyList = ['',' ','@']

14         self.pwList = []

15         self.minLen = 6

16         self.maxLen = 16

17         self.timeout = 3

18         self.flag = 0

19         self.run = {

20    '0':exit,

21    '1':self.getRawList,

22    '2':self.addDenyList,

23    '3':self.clearRawList,

24    '4':self.setRawList,

25    '5':self.modifyPasswordLen,

26    '6':self.createPasswordList,

27    '7':self.showPassword,

28    '8':self.createPasswordFile

29 }

30         self.main()

31

32     def main(self):

33         while True:

34             self.mainMenu()

35             op = input('输入选项:')

36          if op in map(str,range(len(self.run))):

37              self.run.get(op)()

38          else:

39              self.tipMainMenuInputError()

40              continue

41

42     def mainMenu(self):

43      self.clear()

44      print('||'),

45      print('='*40),

46      print('||')

47      print('|| 0:退出程序')

48      print('|| 1:输入密码原始字符串')

49      print('|| 2:添加非法字符到列表')

50      print('|| 3:清空原始密码列表')

51      print('|| 4:整理原始密码列表')

52      print('|| 5:改变默认密码长度(%d-%d)' %(self.minLen,self.maxLen))

53      print('|| 6:创建密码列表')

54      print('|| 7:显示所有密码')

55      print('|| 8:创建字典文件')

56      print('||'),

57      print('='*40),

58      print('||')

59      print('当前非法字符为:%s' %self.denyList)

60      print('当前原始密码元素为:%s' %self.rawList)

61      print('共有密码%d个' %len(self.pwList))

62      if self.flag:

63          print("已在当前目录创建密码文件dic.txt")

64      else:

65          print("尚未创建密码文件")

66

67     def clear(self):

68      OS = platform.system()

69      if (OS == u'Windows'):

70          os.system('cls')

71      else:

72          os.system('clear')

73

74      def tipMainMenuInputError(self):

75      self.clear()

76      print("只能输入0-7的整数,等待%d秒后重新输入" %timeout)

77      time.sleep(timeout)

78

79      def getRawList(self):

80       self.clear()

81       print("输入回车后直接退出")

82       print("当前原始密码列表为:%s" %self.rawList)

83       st = None

84       while not st == '':

85           st = input("请输入密码元素字符串:")

86           if st in self.denyList:

87               print("这个字符串是预先设定的非法字符串")

88               continue

89           else:

90               self.rawList.append(st)

91               self.clear()

92               print("输入回车后直接退出")

93               print("当前原始密码列表为:%s" %self.rawList)

94

95      def addDenyList(self):

96       self.clear()

97       print("输入回车后直接退出")

98       print("当前非法字符为:%s" %self.denyList)

99       st = None

100       while not st == '':

101           st = input("请输入需要添加的非法字符串:")

102           self.denyList.append(st)

103           self.clear()

104           print("输入回车后直接退出")

105           print("当前非法字符列表为:%s" %self.denyList)

106

107      def clearRawList(self):

108       self.rawList = []

109

110      def setRawList(self):

111       a = set(self.rawList)

112       b = set(self.denyList)

113       self.rawList = []

114       for str in set(a - b):

115           self.rawList.append(str)

116

117       def modifyPasswordLen(self):

118       self.clear()

119       while True:

120           print("当前密码长度为%d-%d" %(self.minLen,self.maxLen))

121           min = input("请输入密码最小长度:")

122          max = input("请输入密码最大长度:")

123          try:

124              self.minLen = int(min)

125              self.maxLen = int(max)

126          except ValueError:

127              print("密码长度只能输入数字[6-18]")

128              break

129         if self.minLen not in range(6,19) or self.maxLen not in range(6,19):

130              print("密码长度只能输入数字[6-18]")

131              self.minLen = 6

132              self.maxLen = 16

133              continue

134         if self.minLen == self.maxLen:

135              res = input("确定将密码长度设定为%d吗?(Yy/Nn)" %self.minLen)

136              if res not in list('yYnN'):

137                  print("输入错误,请重新输入")

138                  continue

139              elif res in list('yY'):

140                  print("好吧,你确定就好")

141                  break

142              else:

143                  print("给个机会,改一下吧")

144                  continue

145          elif self.minLen > self.maxLen:

146              print("最小长度比最大长度还大,可能吗?请重新输入")

147              self.minLen = 6

148              self.maxLen = 16

149              continue

150          else:

151              print("设置完毕,等待%d秒后回主菜单" %self.timeout)

152              time.sleep(self.timeout)

153              break

154

155      def createPasswordList(self):

156      titleList = []

157      swapcaseList = []

158      for st in self.rawList:

159          swapcaseList.append(st.swapcase())

160          titleList.append(st.title())

161      sub1 = []

162      sub2 = []

163      for st in set(self.rawList + titleList + swapcaseList):

164          sub1.append(st)

165         for i in range(2,len(sub1) + 1):

166             sub2 += list(itertools.permutations(sub1,i))

167         for tup in sub2:

168             PW = ''

169             for subPW in tup:

170                 PW += subPW

171             if len(PW) in range(self.minLen,self.maxLen + 1):

172                 self.pwList.append(PW)

173             else:

174                 pass

175

176         def showPassword(self):

177         for i in range(len(self.pwList)):

178             if i%4 == 0:

179                 print("%s\n" %self.pwList[i])

180             else:

181                 print("%s\t" %self.pwList[i]),

182         print('\n')

183         print("显示%d秒,回到主菜单" %self.timeout)

184         time.sleep(self.timeout)

185

186         def createPasswordFile(self):

187         print("当前目录下创建字典文件:dic.txt")

188         time.sleep(self.timeout)

189         with open('./dic.txt','w+') as fp:

190             for PW in self.pwList:

191                 fp.write(PW)

192                 fp.write('\n')

193         self.flag = 1

194

195

196     if __name__ == '__main__':

197     mp = MakePassword()


按Esc键,进入命令模式后输入:wq,保存mkPassFileClass.py。mkPassFileClass.py和mkPassFileFunction.py实质上没有什么区别,只是一个使用的是C语言风格的函数调用,一个使用的是C++风格的类实例化。执行命令:


python3 mkPassFileClass.py


得到的结果如图2所示。

图2  运行mkPassFileClass.py

执行结果完全一样。这种C++的写法好处就是调用过程简单,不再关心类具体的实现过程,只需要调用其功能即可;但随之而来就是类的继承、函数重载等麻烦。这种写法在写大项目时可能非常有用,写小程序也行,只是没有那么多优势了。


这个程序还有一个问题,就是在创建密码文件前并没有估算磁盘剩余空间是否足够。一般的解决办法是先估算密码文件的大小,然后创建一个大小相同的空文件,能创建成功就继续运行程序,不能则抛出异常。

微信公众号:计算机与网络安全

ID:Computer-network

【推荐书籍】

登录查看更多
0

相关内容

《信息与软件技术》是一本国际档案期刊,主要关注有助于改进软件开发实践的研究和经验。该杂志的范围包括更好地设计软件和管理其开发的方法和技术。提交审查的文章应该有一个明确的软件工程的组成部分,或者说明如何改进软件开发的工程和管理。官网地址: http://dblp.uni-trier.de/db/journals/infsof/index.html
【实用书】学习用Python编写代码进行数据分析,103页pdf
专知会员服务
190+阅读 · 2020年6月29日
一份简明有趣的Python学习教程,42页pdf
专知会员服务
76+阅读 · 2020年6月22日
【干货书】流畅Python,766页pdf,中英文版
专知会员服务
223+阅读 · 2020年3月22日
《代码整洁之道》:5大基本要点
专知会员服务
49+阅读 · 2020年3月3日
【书籍推荐】简洁的Python编程(Clean Python),附274页pdf
专知会员服务
173+阅读 · 2020年1月1日
机器学习入门的经验与建议
专知会员服务
90+阅读 · 2019年10月10日
用 Python 开发 Excel 宏脚本的神器
私募工场
26+阅读 · 2019年9月8日
Python3.8新特性概览
Python程序员
4+阅读 · 2018年12月8日
手把手教你用Python库Keras做预测(附代码)
数据派THU
14+阅读 · 2018年5月30日
实战 | 用Python做图像处理(三)
七月在线实验室
15+阅读 · 2018年5月29日
Python3.7中一种懒加载的方式
Python程序员
3+阅读 · 2018年4月27日
教你用Python来玩跳一跳
七月在线实验室
6+阅读 · 2018年1月2日
Python NLP入门教程
计算机与网络安全
8+阅读 · 2017年11月21日
Python3爬虫之入门和正则表达式
全球人工智能
7+阅读 · 2017年10月9日
用 Scikit-Learn 和 Pandas 学习线性回归
Python开发者
9+阅读 · 2017年9月26日
代码这样写不止于优雅(Python版)
数说工作室
4+阅读 · 2017年7月17日
Arxiv
10+阅读 · 2020年4月5日
Meta-Learning to Cluster
Arxiv
17+阅读 · 2019年10月30日
Embedding Logical Queries on Knowledge Graphs
Arxiv
3+阅读 · 2019年2月19日
Feature Selection Library (MATLAB Toolbox)
Arxiv
7+阅读 · 2018年8月6日
VIP会员
相关VIP内容
【实用书】学习用Python编写代码进行数据分析,103页pdf
专知会员服务
190+阅读 · 2020年6月29日
一份简明有趣的Python学习教程,42页pdf
专知会员服务
76+阅读 · 2020年6月22日
【干货书】流畅Python,766页pdf,中英文版
专知会员服务
223+阅读 · 2020年3月22日
《代码整洁之道》:5大基本要点
专知会员服务
49+阅读 · 2020年3月3日
【书籍推荐】简洁的Python编程(Clean Python),附274页pdf
专知会员服务
173+阅读 · 2020年1月1日
机器学习入门的经验与建议
专知会员服务
90+阅读 · 2019年10月10日
相关资讯
用 Python 开发 Excel 宏脚本的神器
私募工场
26+阅读 · 2019年9月8日
Python3.8新特性概览
Python程序员
4+阅读 · 2018年12月8日
手把手教你用Python库Keras做预测(附代码)
数据派THU
14+阅读 · 2018年5月30日
实战 | 用Python做图像处理(三)
七月在线实验室
15+阅读 · 2018年5月29日
Python3.7中一种懒加载的方式
Python程序员
3+阅读 · 2018年4月27日
教你用Python来玩跳一跳
七月在线实验室
6+阅读 · 2018年1月2日
Python NLP入门教程
计算机与网络安全
8+阅读 · 2017年11月21日
Python3爬虫之入门和正则表达式
全球人工智能
7+阅读 · 2017年10月9日
用 Scikit-Learn 和 Pandas 学习线性回归
Python开发者
9+阅读 · 2017年9月26日
代码这样写不止于优雅(Python版)
数说工作室
4+阅读 · 2017年7月17日
Top
微信扫码咨询专知VIP会员