破譯密碼
排列
概念:從n個元素中取出m(m<=n)個元素,按照一定的順序排成一列,叫做從n個元素中取出m個元素的一個排列(Arrangement),特別地,當m=n時,這個排列被稱爲全排列(Permutation)
'''
需求:1 2 3 4
假設從中取3個數字,然後對這三個數字進行排列
'''
#需求:從[1,2,3,4]4個數中隨機取出3個數進行排列
import itertools
myList = list(iterator.permutations([1,2,3,4], 3))
print(mylist)
print(len(mylist))
'''
規律總結:
4 - 3 24
4 - 2 12
4 - 1 4
排列的可能性次數:n!/(n-m)!
'''
組合
概念:從m個不同的元素中,任取n(n<=m)個元素爲一組,叫做從m個不同元素中取出n個元素的進行組合。
import itertools
'''
[1,2,3,4,5]中選取4個數的組合方式有幾種?
'''
myList = list(itertools.combinations([1,2,3,4,5],4))
print(myList)
print(len(muyList))
'''
規律總結:
m n
5 5 1
5 4 5
5 3 10
5 2 10
m!/(n!x(m-n)!)
'''
排列組合
import itertools
myList = list(itertools.product("0123456789QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm",repeat=6))
#可以嘗試,有可能電腦會卡住
#多線程也不行,電腦內存不夠,咋處理都白搭
print(len(myList))
注意:但凡涉及到密碼,一般都會進行加密處理,常見的加密方式有MD5,RSA,DES等。
瘋狂破譯密碼
傷敵一千自損一萬的破解方式
import time
import itertools
password = ("".join(x) for x in itertools.product("0123456789QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm",repeat=6))
#print(len(myList))
while True:
try:
str1 = next(password)
time.sleep(0.5)
print(str1)
except StopIteration as e:
break
正則表達式
常用需求
判斷QQ號
需求:設計一個方法,傳遞一個QQ號,判斷這個QQ號碼是否合法。
'''
分析:
1.全是數字
2.位數:4~11
3.第一位不能爲0
'''
def checkQQ(str1):
#不管傳入的str是否合法,我們假設是合法的
result = True
#尋找條件推翻最初的假設
try:
#判斷是否全部爲數字
num = int(str1)
if len(str1) >= 4 and len(str1) <= 11:
#判斷是否以數字[0]開頭
if str1[0] == '0':
result = False
else:
result = False
except BaseException:
result = False
print(ckeckQQ("123284u3t95"))
正則概述
正則表達式(Regular Exception),使用單個字符串來描述,匹配一系列符合某個語句法則的字符串搜索模式
搜索模式可用於文本搜索和文本替換
正則表達式是由一個字符序列形成的搜索模式
當你在文本中搜索數據時,你可以使用搜索模式來描述你要查詢的內容
正則表達式可以是一個簡單的字符,也可以是一個複雜的模式
正則表達式可用於所有文本搜索和文本替換的操作。
在python中,通過內嵌成re模塊,程序員可以直接調用來實現正則匹配,正則表達式被編譯成一系列的字節碼,然後由c編寫的匹配引擎執行。
模塊簡介
python 自1.5版本增加了re模塊,它提供Perl風格的正則表達式模式
re模塊使python語言擁有全部的正則表達式功能
re模塊提供了與這些方法功能完全一致的函數,這些函數使用一個模式的字符串作爲他們的第一個參數。
正則表達式的元字符
import re
#匹配單個字符與數字
r'''
. 匹配除換行符以外的任意字符
[0123456789] []是字符集合,表示匹配方括號中所包含的任意一個字符
[good] 匹配good中任意一個字符
[a-z] 匹配任意小寫字母
[A-Z] 匹配任意大寫字母
[0-9] 匹配任意數字
[0-9a-zA-Z] 匹配任意的數字和字母
[0-9a-zA-Z_]匹配任意的數字,字母以及下劃線
[^good] 匹配除了good這幾個字母以外的所有字符,中括號裏的^稱爲脫字符,表示不匹配集合中的字符
[^0-9] 匹配所有的非數字字符
\d 匹配數字,效果同[0-9]
\D 匹配非數字字符,效果同[^0-9]
\w 匹配數字,字母和下劃線,效果同[0-9a-zA-Z_]
\W 匹配非數字,字母和下劃線,效果同[^0-9a-zA-Z_]
\s 匹配任意的空白符(空格、回車、換行、製表、換頁),效果同[\r\n\t\f]
\S 匹配任意的非空白符,效果同[^\f\n\r\t]
'''
print(re.findall("\d","you are good1 man"))
r'''
^ 首行匹配,和在[]裏的^不是一個意思
$ 行尾匹配
\A 匹配字符串開始,它和^的區別是,\A只匹配整個字符串的開頭,即使在re.M模式下也不會匹配它行的行首
\Z 匹配字符串結束,它和$的區別是,\Z只匹配整個字符串的結束,即使在re.M模式下也會匹配它行的行尾
\b 匹配一個單詞的邊界,也就是指單詞和空格的位置
'er\b'可以匹配never,不能匹配nerve
\B 匹配非單詞邊界
'''
print(re.search("^good","you are a good man"))
print(re.search("man$","you are a good man"))
print(re.search("^good","you are a good man",re.M))
print(re.search("\Agood","you are a good man",re.M))
print(re.search("man$","you are a good man",re.M))
print(re.search("man\Z","you are a good man",re.M))
print(re.search(r"er\b","never"))
print(re.search(r"er\b","neve"))
print(re.search(r"er\B","never"))
print(re.search(r"er\B","neve"))
'''
說明:下方的x,y均爲假設的普通字符,n,m(非負整數),不是正則表達式的元字符
(xyz) 匹配小括號內的xyz(作爲一個整體去匹配)
x? 匹配0個或者1個x
x* 匹配0個或者任意多個x(.*表示匹配0個或者任意多個字符(換行符除外))
x+ 匹配至少一個x
x{n} 匹配確定的n個x(n是一個非負整數)
x{n,} 匹配至少n個x
x{n,m} 匹配至少n個最多m個x,注意n<=m
x|y |表示或,匹配的是x或y
'''
print(re.findall(r"a?","aaa"))#非貪婪匹配,儘可能少的匹配
print(re.findall(r"a*","aaabaa"))#貪婪匹配,儘可能多的匹配
print(re.findall(r"a+","aaabaaaa"))#貪婪匹配,儘可能多的匹配
print(re.findall(r"a{3}","aaabaaaa"))
print(re.findall(r"a{3,}","aaabaaaa"))#貪婪匹配,儘可能多的匹配
print(re.findall(r"a{3,6}","aaabaaaa"))
print(re.findall(r"(a|A)n","anaabaaaAn"))
需求:提取:you…man
str1 = "you are a good man,you are a nice man ,you are a great man,you are a..."
print(re.findall(r"you.*?man",str1))
'''
*? +? x? 最小匹配,通常都是儘可能多的匹配,可以使用這種貪婪匹配(?:x) 類似於(xyz),但是不表示一個組
'''
#註釋:/* part1 */ /* part2 */
print(re.findall(r"/*.*?/*/",r"/* part1 */ /* part2 */"))
re模塊中常用的功能函數
complie()
編譯正則表達式模式,返回一個對象模式。(可以把那些常用的正則表達式編譯成正則表達式對象,這樣做的目的爲了提高一點效率)
格式:
re.complie(pattern,flags=0)
pattern:編譯時用的表達式字符串
flags:編譯標誌位,用於修改正則表達式的匹配方式,如是否區分大小寫,多行匹配等等。
import re
tt = "Tina is a good girl, she is cool, clever, and so on..."
rr = re.compile(r'\w*oo\w*')
print(rr.findall(tt)) #查找所有包含'oo'的單詞
#執行結果如下:
#['good', 'cool']
match()
決定re是否在字符串的開始的位置進行匹配
注意:這個方法並不是完全匹配,當pattern結束時若string還有剩餘字符,仍然視爲匹配成功
想要完全匹配可以在表達式末尾添加邊界匹配符“$”
語法:
re.match(pattern,string,flags=0)
import re
print(re.match("com","comww.rnfregcoomn").group())
print(re.match("com",'Comwww.runcomoob',re.I).group())
search()函數
語法:
re.search(pattern,string,flags= 0)
re.search函數會在字符串中查找模式匹配,只要找到第一個匹配然後返回,若沒有找到匹配則返回None
import re
print(re.search('\dcom','www.4comrunoob.5com').group())
#執行結果如下:
#4com
findall()
re.findall遍歷匹配,可以獲取字符串中所有匹配的字符串,返回一個列表
語法:
re.findall(pattern,string,flag=0)
import re
p = re.compile(r"\d+")
print(p.findall('o1n2m3k4'))
#執行結果如下:
#['1', '2', '3', '4']
import re
tt = "Tina is a good girl, she is cool, clever, and so on..."
rr = re.compile(r'\w*oo\w*')
print(rr.findall(tt))
print(re.findall(r'(\w)*oo(\w)',tt))#()表示子表達式
#執行結果如下:
#['good', 'cool']
#[('g', 'd'), ('c', 'l')]
finditer()
搜索string,返回一個順序訪問每一個匹配結果(Match對象)的迭代器,找到RE匹配的所有子串,並把他們作爲一個迭代器返回。
語法:
re.finditer(pattern,string,flags=0)
import re
iter = re.finditer(r'\d+','12 drumm44ers drumming, 11 ... 10 ...')
for i in iter:
#print(i)
#print(i.group())
print(i.span())
"""
執行結果如下:
<_sre.SRE_Match object; span=(0, 2), match='12'>
12
(0, 2)
<_sre.SRE_Match object; span=(8, 10), match='44'>
44
split()
按照能夠匹配子串將string分割後返回列表
可以使用re.split來分割字符串。
語法:
re.split(pattern,string[,maxsplit])
maxsplit用於指定最大的分割次數,若不指定則全部分割。
import re
print(re.split('\d+','one1two2three3four4five5'))
#執行結果如下:
#['one', 'two', 'three', 'four', 'five', '']
sub()
使用re替換string中每一個匹配的子串後返回替換後的新串。
語法:
re.sub(pattern,repl,string,count)
參數一:要匹配的字符串,參數二:要替換的字符串
參數三:要匹配的內容 參數四:指定替換的個數
import re
text = "Bob is a handsome boy, he is cool, clever, and so on..."
print(re.sub(r'\s+', '-', text))
#執行結果如下:
#JGood-is-a-handsome-boy,-he-is-cool,-clever,-and-so-on...
#其中第二個函數是替換後的字符串;本例中爲'-'
#第四個參數指替換個數。默認爲0,表示每個匹配項都替換。
注意:
1.re.match() 與re.search()還有re.findall()區別
re.match只匹配字符串的開始,re.search匹配整個字符串,返回第一個匹配結果,re.findall整個字符串,返回所有的匹配結果。