【2018/10/19测试T1】加密

本文深入探讨了如何通过逆向工程解析一种特定的加密算法,包括使用扩展欧几里得算法来解决模方程,以及如何通过位操作和哈希表优化查询效率。通过具体的代码实现,展示了如何在O(Q*log n)的时间复杂度内还原加密过程。

【题目】

内网传送门
外网传送门

【分析】

30 pts:

枚举 1 1 1 1 0 7 10^7 107 的所有数,存入哈希表,然后 O ( 1 ) (1) (1) 查询单个询问。

100 pts:

正解思路就是如何倒序还原每步操作。

关于 t = t + ( t &lt; &lt; i ) t=t+(t&lt;&lt;i) t=t+(t<<i),相当于是解: ( 2 i + 1 ) &ThickSpace; x ≡ t &ThickSpace; ( m o d &ThickSpace; 2 32 ) (2^i+1)\;x\equiv t\;(mod\;2^{32}) (2i+1)xt(mod232),可以用扩展欧几里得算法还原这一步。

关于 t = t ∧ ( t &gt; &gt; i ) t=t∧(t&gt;&gt;i) t=t(t>>i),考虑把运算之前的 t t t 分为 ⌈ 32 i ⌉ \lceil\frac{32}{i}\rceil i32 份,相当于除了第一份,其他的每一份都异或上了前面的一部分。第一份确定,其余部分也可以确定。

于是,我们可以在 O ( Q ∗ l o g &ThickSpace; n ) (Q*log\;n) (Qlogn) 的时间内解决。

【代码】

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const long long Mod=1ll<<32ll;
long long Multiply(long long a,long long b)
{
	long long ans=0;
	while(b)
	{
		if(b&1)
		  ans=(ans+a)%Mod;
		a=(a+a)%Mod;
		b>>=1;
	}
	return ans;
}
void exgcd(long long a,long long b,long long &x,long long &y)
{
	if(!b)
	{
		x=1,y=0;
		return;
	}
	exgcd(b,a%b,y,x);
	y-=a/b*x;
}
long long cinv(long long t)
{
	long long x,y;
	exgcd(t,Mod,x,y);
	return x=(x+Mod)%Mod;
}
int main()
{
//	freopen("encrypt.in","r",stdin);
//	freopen("encrypt.out","w",stdout);
	int n,i;
	long long t;
	scanf("%d",&n);
	for(i=1;i<=n;++i)
	{
		scanf("%lld",&t);
		long long x1,x2,x3,x4,x5,x6;
		t=Multiply(t,cinv((1<<16)+1));
		
		x1=t>>22;
		x2=(t>>11)^(x1<<11);
		x3=t^(x1<<22)^(x2<<11);
		x2^=x1,x3^=x2;
		t=(x1<<22)^(x2<<11)^x3;
		
		t=Multiply(t,cinv((1<<3)+1));
		
		x1=t>>30;
		x2=(t>>24)^(x1<<6);
		x3=(t>>18)^(x1<<12)^(x2<<6);
		x4=(t>>12)^(x1<<18)^(x2<<12)^(x3<<6);
		x5=(t>>6)^(x1<<24)^(x2<<18)^(x3<<12)^(x4<<6);
		x6=t^(x1<<30)^(x2<<24)^(x3<<18)^(x4<<12)^(x5<<6);
		x2^=x1,x3^=x2,x4^=x3,x5^=x4,x6^=x5;
		t=(x1<<30)^(x2<<24)^(x3<<18)^(x4<<12)^(x5<<6)^x6;
		
		t=Multiply(t,cinv((1<<10)+1));
		printf("%lld\n",t);
	}
//	fclose(stdin);
//	fclose(stdout);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值