版权声明:转载注明出处,大家一起交流 https://blog.csdn.net/qq_38231051/article/details/82392330
链接:http://acm.hit.edu.cn/problemset/1012
这个题考的就是一个异或运算。
话说英语差真的有毒,题目看了老半天不知道是啥......
题目的核心就是通过给出的两个加密后的数据,一个是N字节,一个是N+1字节。其中N+1字节的数据就是开头多了一个空格,而空格对应的十进制数是32,之后的原始数据和N字节的数据是一致的。通过这个来推出N+1字节对应的N+1字节长度的密钥。
思路是这样的:由已知的空格可以推出第一个字节的密钥,第一字节的密钥和N字节的第一字节异或可以得出原文的第一个字节,而原文的第一字节对应N+1字节的第二个字节的原文,相互异或又可以得出第二个字节的密钥。
以此类推,可以一步步得出N+1字节的密钥。
由于16进制的转化有点麻烦,没能在睡前写出代码来。这题就只能贴一下思路了。如果思路有问题还望指正。
补个ac代码,感谢Leowner作为我博客生涯的第一个评论,嘿嘿嘿。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char a[20004];
char b[20004];
char c[20004];
int ten(int i,char* x)
{
int k;
if(x[2*i]>='A'){
k = (10+x[2*i]-'A')*16;
}else
k = (x[2*i]-'0')*16;
if(x[2*i+1]>='A'){
k += (10+x[2*i+1]-'A');
}else
k += (x[2*i+1]-'0');
return k;
}
void setnum(int first,int end,int i)
{
if(first>=10){
c[2*i] = 'A'+first-10;
}else
c[2*i] = '0'+first;
if(end>=10){
c[2*i+1] = 'A'+end-10;
}
else
c[2*i+1] = '0'+end;
}
void getit(int len)
{
int first,end;
int i=0,j=0;
int temp=32;
int result;
int A=0;
A = ten(0,b);
result = A^temp;
first = result/16;
end = result%16;
setnum(first,end,i);
++i;
int k=0;
for(k=0;k<len/2;++k)
{
temp = result^ten(k,a);
A = ten(k+1,b);
result = A^temp;
first = result/16;
end = result%16;
setnum(first,end,k+1);
++i;
}
c[(k+1)*2]='\0';
}
int main()
{
int temp,len;
while(scanf("%s %s",a,b)!=EOF){
getit(strlen(a));
printf("%s\n",c);
}
}