1 条题解
-
0
解题思路分析
本题的核心在于利用两个加密消息之间的关联,通过异或运算的性质恢复密钥。关键在于分析两条消息对应的明文关系,结合异或运算的可逆性推导密钥。 问题建模 设两条加密消息对应的明文分别为:
第一条明文:(长度为 N)第二条明文:(长度为 ,开头添加空格字符 32) 设密钥为 ,则根据加密规则: 第一条加密消息:()第二条加密消息:(,其中 ,)
关键推导
推导 第二条明文的第一个字节为 32,对应加密结果 ,因此:推导 对于 ,第二条明文的第 i 字节等于第一条明文的第 字节,即 。 根据加密规则:$E_1[i-1] = K_{i-1} \oplus C_{i-1} \quad \text{(第一条消息)}$ 将两式相异或(消去 ): 由于 已知(通过前序推导),可递推得到 :
实现步骤
输入解析
将两条十六进制加密消息转换为字节数组(整数形式)。第一条消息长度为 N,对应字节数为 N;第二条长度为 N+1,对应字节数为 N+1。初始化
密钥
计算 :通过第二条消息的第一个字节与 32 异或得到。递推计算后续密钥 对于 i 从 2 到 :取第一条消息的第 字节(索引从 0 开始)和第二条消息的第 字节。通过异或运算递推得到 。
输出结果
将密钥数组转换为十六进制字符串(大写,两位表示每个字节)。编辑分享如何进一步分析两条消息对应的明文关系?有没有其他方法可以恢复密钥?密钥的长度对恢复过程有什么影响?
代码
#include <cstring> #include <iostream> #include <algorithm> using namespace std; const int N=10001; inline int cread(){ int ch=getchar(); while((ch<'0'||ch>'9')&&(ch<'A'||ch>'F')&&ch!='\n'){ if(ch==EOF) return -2; ch=getchar(); } if(ch=='\n') return -1; if(ch>='0'&&ch<='9') return ch-'0'; return ch-'A'+10; } short a[N],len; int main(){ int x=cread(),y; while(x!=-2){ len=0; while(1){ if(x==-1) break; y=cread(); a[len++]=x*16+y; x=cread(); } int ex=32; for(int i=0;i<=len;i++){ x=cread(),y=cread(); int b=x*16+y; ex=b^ex; printf("%02X",ex); ex=ex^a[i]; } puts(""); x=cread(); while(x==-1) x=cread(); } return 0; }
- 1
信息
- ID
- 1175
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 5
- 已通过
- 1
- 上传者