Ctfshow 密码挑战--真·Beginner

题目:

assert(len(open('flag.txt', 'rb').read()) <= 50)
assert(str(int.from_bytes(open('flag.txt', 'rb').read(), byteorder='big') << 10000).endswith('1002773875431658367671665822006771085816631054109509173556585546508965236428620487083647585179992085437922318783218149808537210712780660412301729655917441546549321914516504576'))

没见过int.from_bytes和endswith函数,先学一学:

与int.from_bytes对应的还有int.to_bytes。

1、int.from_bytes

函数格式:int.from_bytes(bytes, byteorder, *, signed=False),bytes为输入的变量,byteorder有'big'和'little',signed有'True'和'False'。

作用:把bytes类型的变量,转化为十进制整数

举例1:int_s  = int.from_bytes(s, byteorder='little', signed=True),且s = '\xf1\xff'。

byteorder='little',表示高位在前,低位在后,s = '\xf1\xff','\x'表示16进制,而f1是低位,ff是高位,故把ff放前面,f1放后面。先将f1和ff分别写成二进制f1 = 1111 0001,ff = 1111 1111。如果byteorder='big',则是正常顺序,低位在前,高位在后。

再看signed=True。表示要区分二进制数的正负。ff第一位为1,则是负数,故要进行取反加一操作,符号位不变。得到10000000 00001111,对应十进制为-15.如果signed=False,则无符号位。

举例2:int_s  = int.from_bytes(s, byteorder='big', signed=False),且s = '\xf1\xff'。

得到二进制(1111 0001 1111 1111),故转十进制int_s = 61951 

2、int.to_bytes

上面操作的逆过程,将十进制整数转为bytes类型

 endswith

作用判断字符串是否以指定字符或子字符串结尾,常用于判断文件类型。

再来看:

assert(str(int.from_bytes(open('flag.txt', 'rb').read(), byteorder='big') << 10000).endswith('1002773875431658367671665822006771085816631054109509173556585546508965236428620487083647585179992085437922318783218149808537210712780660412301729655917441546549321914516504576'))

将二进制的明文进行左移10000操作,即乘上2*10000,并给了转成十进制后的明文的后175位。

故可以得到下面的关系式:

c = 2^10000 * m (mod 10^175),推导一下:

2^10000 * m/c = 1 (mod 10^175),故m/c就等于2^10000关于1模10^175的逆元,通过计算发现,该逆元不存在,因为2^10000和10^175间有公因数2^175,把它约去即可

代码如下: 

from gmpy2 import *
from Crypto.Util.number import *

c = 1002773875431658367671665822006771085816631054109509173556585546508965236428620487083647585179992085437922318783218149808537210712780660412301729655917441546549321914516504576

x = invert(pow(2,10000),pow(5,175))
m = c*x%(pow(5,175))
print(long_to_bytes(m))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值