WKCTF_How to encrypt?
大约 2 分钟
How to encrypt
exp:
import torch
import torch.nn as nn
import numpy as np
# 解决报错:OMP: Error #15: Initializing libiomp5md.dll, but found libiomp5md.dll already initialized.
import os
os.environ["KMP_DUPLICATE_LIB_OK"] = "TRUE"
# 读取文件并解析密文数据
ch = []
with open('ciphertext.txt', 'r') as file:
for line in file:
try:
line_numbers = line.strip().split()
ch.append([float(num) for num in line_numbers])
except ValueError:
print(f"Ignored non-numeric line: {line}")
print(len(ch))
n = len(ch)-1
# 定义加密网络
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
self.linear = nn.Linear(n, n*n)
self.conv = nn.Conv2d(1, 1, (2, 2), stride=1, padding=1)
def forward(self, x):
x = self.linear(x)
x = x.view(1, 1, n, n)
x = self.conv(x)
return x
# 加载训练好的模型参数
mynet=Net()
mynet.load_state_dict(torch.load('model.pth'))
conv_weight = mynet.conv.weight.data.tolist()[0][0]
print(conv_weight)
conv_bias = mynet.conv.bias.data.tolist()
print(conv_bias)
linear_weight = mynet.linear.weight.data.tolist()
print(linear_weight[0])
linear_bias = mynet.linear.bias.data.tolist()
print(len(linear_bias))
# 解密
'''
初始化 flag 数组,用于存储解密后的数据
遍历 ch 中的每个元素,通过逆向操作计算出原始数据。具体操作包括减去卷积层的偏置和加权值,然后除以卷积核的权重。
逆卷积操作
对于卷积层,卷积核的大小为 2x2,并且在正向操作中,卷积公式为:
output[i][j]=conv_weight[0][0]×input[i][j]+conv_weight[0][1]×input[i][j+1]+conv_weight[1][0]×input[i+1][j]+conv_weight[1][1]×input[i+1][j+1]+conv_bias
将 flag 转换为适当的形状,并减去全连接层的偏置。
使用全连接层权重的伪逆矩阵对 flag 进行矩阵运算,得到解密后的数据。
将解密后的数据转换为字符并打印出来,形成解密后的文本。
'''
flag = [[0]*n for _ in range(n)]
for i in range(n):
for j in range(n):
x = 0
y = 0
z = 0
if i>0:
y = flag[i-1][j]
if j>0:
x = flag[i-1][j-1]
if j>0:
z = flag[i][j-1]
# 减去卷积层的偏置 conv_bias[0] 和邻近元素的加权和,再除以卷积核 conv_weight[1][1]。
flag[i][j]=ch[i][j]-conv_bias[0]-(conv_weight[0][0]*x+conv_weight[0][1]*y+conv_weight[1][0]*z)
flag[i][j]/=conv_weight[1][1]
# 转换和偏置调整
'''
将 flag 转换为一维数组。
减去全连接层的偏置 linear_bias。
将 flag 重新调整为 (n*n, 1) 的形状。
'''
flag = np.array(flag).reshape(n*n)
flag = flag-linear_bias
flag = flag.reshape(n*n,1)
print(flag.shape)
print(np.array(linear_weight).shape)
print(np.linalg.pinv(linear_weight).shape)
# 使用全连接层权重 linear_weight 的伪逆矩阵对 flag 进行矩阵运算,得到解密后的数据。
flag = np.linalg.pinv(linear_weight).dot(flag)
for i in flag:
print(chr(round(i[0])),end='')
得到flag:
flag{Mi_muhe_mosi!Mi_muhe_mita,mita_movo_lata!}