话不多说 参考大佬的代码然后进行更改和理解。
网上很多人都是运用的这位大佬的代码。链接如下Hacking8信息流邀请码Writeup | Linkle'Blog
但是直接使用发现跑了半天结果没有任何输出。
原因分析缺少 from __future__ import division 导致1/3=0。 大家可以自行python,然后输入1/3查看结果。加上后会出现1/3=0.333333333333。
所以需要将 from __future__ import division 加在文件头!!!!!! 部分函数及其作用讲解: 一、ops=["+", "-", "*", "/", "%", "^"]
a = [ops for _ in range(8)]
结果为a[0]=a[1]=……a[7]=["+", "-", "*", "/", "%", "^"]
二、s = "1%s2%s3%s4%s5%s6%s7%s8%s9"
for x in tqdm(itertools.product(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7]), total=1679616)
exp = s % x
先解释 itertools.product(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7])
笛卡尔积 排序组合 8的6次方组合 即 a[0]-a[7] 8个数组中 从["+", "-", "*", "/", "%", "^"] 中6取1。
三、for x in tqdm(itertools.product(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7]) , total=1679616)
exp = s % x
exp等于 将x 代入 8的6次方组合 中的a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7] 代入s 总共1679616次
举例 a[0]=a[1]=……a[7]="+"
exp=1+2+3+4+5+6+7+8+9
靠eval()计算得出结果result
如果就这样理论上应该可以计算结果,但是由于指数过大会造成程序错误如7**8**9 python就会无法计算报错。需要拆分计算。所以无法采用暴力破解。由于本人编程能力有限,所以还是按照大佬的代码进行。
四、pos = [substr.start() for substr in re.finditer('^' , exp)]
如果所有符合为乘法 1x2x3x4x5x6x7x8x9=362880<95551487 。所以一定存在** 次方运算。
采用 if 和else 这里将排除不存在**的情况。
将所有**的可能性选择出来并进行计算。 那么总共的计算方式从1679616减少为 7的6次方*8种可能 941192 。再去掉连续次方的存在的情况。
for i in range(len(pos)):
try:
if pos[i+1]-pos[i] <= 2:
break
except IndexError:
pass
if i != len(pos)-1: 将跳出循环的 if pos[i+1]-pos[i] <= 2: 情况 直接 continue过滤 循环到最后的 i== len(pos)-1 所以会执行eval()
continue
最后的组合 很快就能算出。
最后请懂的大佬解惑。
为什么直接6**7**8 会计算很慢很慢。
但是采用eval("6**7**8") ==12312312312 进行比较 很快就能返回结果。
以下为我理解后粗略的代码 2个代码速度比较后,比大佬的快一些,但是后续扩展性差。
# -*- coding: utf-8 -*
from __future__ import division
ops = ["+", "-", "*", "/", "%", "**"]
a = [ops for _ in range(8)]
s = "1%s2%s3%s4%s5%s6%s7%s8%s9"
for i in range(6) :
for j in range(6) :
for k in range(6) :
for l in range(6) :
if(k==5 and l==5):
continue
for m in range(6) :
if(m==5 and l==5):
continue
for n in range(6) :
if(m==5 and n==5):
continue
for o in range(6):
if(o==5 and n==5):
continue
for p in range(6):
if(p==5 and o==5):
continue
exp = s % (a[0][i],a[1][j],a[2][k],a[3][l],a[4][m],a[5][n],a[6][o],a[7][p])
result = eval(exp)
if(result==95551487):
print (exp)
以下为大佬的代码 需要在文件头添加 from __future__ import division
import re
import itertools
from tqdm import tqdm # 进度条
ops = ["+", "-", "*", "/", "%", "^"]
a = [ops for _ in range(8)]
s = "1%s2%s3%s4%s5%s6%s7%s8%s9"
for x in tqdm(itertools.product(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7]), total=1679616):
exp = s % x
pos = [substr.start() for substr in re.finditer('^' , exp)]
if len(pos) > 0:
for i in range(len(pos)):
try:
if pos[i+1]-pos[i] <= 2:
break
except IndexError:
pass
if i != len(pos)-1:
continue
else:
continue
result = eval(exp.replace("^","**")) # python中**计算次方
if result == 95551487:
print("key: ", exp)


