刷题记录-背包密码两题

背包密码

例如,构造超递增序列

a=\left [ 2,3,6,13,27,52 \right ]

假设背包重量为70,我们发现
52<70,所以52在背包中,70-52=18
27>18,所以27不在背包中
13<18,所以13在背包中,18-13=5
6>5,所以6不在背包中
3<5,所以3在背包中,5-3=2
2=2,所以2在背包中,2-2=0.

DASCTF20247月-complex_enc

from Crypto.Util.number import *
import random
from secret import flag


def GET_KEY(n):
    sum=2
    key=[1]
    for i in range(n):
        r=random.randint(0,1)
        x=sum+random.randint(0,n)*r
        key.append(x)
        sum+=x
    return key

def enc(m,k):
    cipher_list = []
    for i in range(len(m)):
        if m[i] == 1:
            cipher_list.append(m[i] * k[i])
    cipher = sum(cipher_list)
    return cipher

m=bytes_to_long(flag)
m = [int(bit) for byte in flag for bit in format(byte, '08b')]
key=GET_KEY(len(m))
c=enc(m,key)

with open('output.txt', 'w') as f:
    f.write(str(c))
    f.write(str(key))


先用一个生成长度为n的密钥的函数,先随机取第一个元素放到key中,同时用sum记录密钥中元素之和,这里的r会随机取0、1,使后面每次生成的元素可能是前面所有数之和,也可能会多一点,将生成的所有元素作为密钥中的元素再将生成的密钥加到key中,并用sum记录所有密钥元素之和,如此循环往复,可以生成一段超递增序列作为密钥。

这段加密函数的两个参数,都为列表,且m为由0,1组成的列表,后面对明文进行了处理变成了这个形式,然后这里m只有0,1,就相当于求m和k两个向量的数量积,将m为1的项与k对应的项相乘在求和得到密文。

就是当W>an时,才有an。m[i]=1

EXP


from Crypto.Util.number import *
#对私钥重排
def relist(pub):
    a = pub[:]
    c = []
    while a:  # 当a不为空时
        m = min(a)
        c.append(m)
        a.remove(m)
    return c
#解密
def resolve(pub,a,w):
    b=[]
    for j in range(1,len(a)):
        b.append(0)     #用0填充方便后面替换
    for i in range(1,len(a)):
        an=a[len(a)-i-1]
        id=pub.index(an)
        if w<an:
            None
        else:
            w=w-an
            b[id:id+1]=[1]  #将0替换成1
    if w==0:    #说明解密完成
        return b

def decrypto(pub,w):
    a=relist(pub)
    m=resolve(pub,a,w)
    return m
c= 
key=

m=decrypto(key,c)
print(m)
ml=''
for i in range(len(m)):
    ml+=str(m[i])
print(long_to_bytes(int(ml,2)))

BaseCTF-2024-week1-babypack

from Crypto.Util.number import *
import random
flag=b'BaseCTF{}'
m=bytes_to_long(flag)
bin_m=bin(m)[2:]
length=len(bin_m)
a=[1]
sum=1
for i in range(length-1):
    temp=random.randint(2*sum+1,4*sum)
    sum=sum+temp
    a.append(temp)
a=a[::-1]
c=0
for i in range(length):
    if bin_m[i]=='1':
        c=c+a[i]
print("a=",a)
print("c=",c)

这里的a是一个超递增序列,每次我们比较一下c[i]和a[i],如果c>a,那么m[i]就等于1

EXP

from Crypto.Util.number import *
# a=
c=24886562958079299354043165561947473141759778607555940148388795515259155580420
0373536391905463203635903903983185413495772503475035384778216803353752385428842
7613513938991943920607437000388885418821419115067060003426834
bin_m=""
for i in a:
    if c>=i:
        bin_m+="1"
        c=c-i
else:
    bin_m+="0"
    m=int(bin_m,2)
print(long_to_bytes(m))

  • 9
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值