2021强网杯 ezmath

"这篇博客探讨了一个在2021年强网杯中遇到的数学问题,涉及double数组和递推关系。通过分析函数sub_13F3中的递推公式an+1=e^(-n*an),发现序列不收敛。作者尝试通过改变递推关系使其收敛,并观察数组元素ei/e近似整数,最终确定了可能的flag内容。通过对序列进行处理,得到了可能的flag{saam_dim_gei_lei_jam_caa_sin_laa}
摘要由CSDN通过智能技术生成

2021强网杯 reverse ezmath

奇怪的思路,但也算是出了flag。
在这里插入图片描述
bdl_4020是一个double数组,内容是19个小数。

sub_13F3函数如图:
在这里插入图片描述
v3的初值是0.2021,但是在运行过程中修改成了0.000483

v3是一个递推的关系,递推公式是 a n + 1 = e − n × a n a_{n+1}=e-n\times a_n an+1=en×an

用python简单的打一个表,可以发现v3初值无论为多少,经过80次左右的循环后,都会在正负无穷之间跳跃。

>>> v3 = [0.000483]
>>> for i in range(0x2021,0x2021+100):
	v3.append(math.e-i*v3[-1])

	
>>> v3[-20:]
[-inf, inf, -inf, inf, -inf, inf, -inf, inf, -inf, inf, -inf, inf, -inf, inf, -inf, inf, -inf, inf, -inf, inf]

v3是不收敛的,更不用说令v3等于double数组中的小数值。

多种尝试无果,于是尝试让 a n a_n an强行收敛试试,也就是令

lim ⁡ n → + ∞ a n + 1 = a n \lim\limits_{n\to+\infty}a_{n+1}=a_n n+liman+1=an

a n + 1 = a n = e − n ∗ a n a_{n+1}=a_n=e-n*a_n an+1=an=enan

化简得:

lim ⁡ n → + ∞ a n + 1 = a n = e n + 1 = e n \lim\limits_{n\to+\infty}a_{n+1}=a_n=\frac{e}{n+1}=\frac{e}{n} n+liman+1=an=n+1e=ne

很奇怪但大家懂这意思就行

观察double数组中的值, e i \frac{e}{i} ie的值都接近整数

>>> [math.e/i for i in dbl]
[27751.99996396786, 26466.999962218535,29564.999966177365,
24930.99995989091,24430.999959070075, 26981.999962939633, 
24430.999959070075, 25960.999961482154, 24426.999959063374, 
25965.99996148958, 24426.999959063374, 24939.999959905384,
24430.999959070075, 24932.99995989413, 24418.999959049965, 
26996.999962960217, 24431.999959071745, 24941.999959908593,
32098.999968847354]

可以初步判断是正确的

于是把 e i \frac{e}{i} ie 的值作为flag内容
代码如下

from math import *
a = [0.00009794904266317233, 0.00010270456917442, 0.00009194256152777895,\
     0.0001090322021913372, 0.0001112636336217534, 0.0001007442677411854,\
     0.0001112636336217534, 0.0001047063607908828, 0.0001112818534005219,\
     0.0001046861985862495, 0.0001112818534005219, 0.000108992856167966,\
     0.0001112636336217534, 0.0001090234561758122, 0.0001113183108652088,\
     0.0001006882924839248, 0.0001112590796092291, 0.0001089841164633298,\
     0.00008468431512187874]
aa = [round(e/i) for i in a]

def f(n):
    b = bin(n)[2:].zfill(16)
    return chr(int(b[8:],2))+chr(int(b[:8],2))
    #是后半段+前半段,要反过来
print(''.join(f(i) for i in aa))

#===============输出========================
#hlcg}scao_fio_iek_nek_lao_eac_uip_nac}

很明显有flag的形式了,但是需要调整。

前缀“ flag{ ”与输出“ hlcg} ”,观察得到,是每两个字符的前一个字符,对应ASCII码+2即可。

于是修改函数的返回值

def f(n):
    b = bin(n)[2:].zfill(16)
    return chr(int(b[8:],2)-2)+chr(int(b[:8],2))
   #这里减2

得到输出

flag{saam_dim_gei_lei_jam_caa_sin_laa}

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值