HDU 2466 Cryptography Reloaded (数论+高精度)
2015-11-12 00:45
441 查看
HDU 2466
选两个大素数 p , q,令 n=p∗q,那么 φ(n)=(p−1)(q−1),
再选一个 φ(n)以内的数字 e ,计算出 d ,使 e∗d=1 mod φ(n)。当选择的 e 太小时很容易被暴力破解,现在给你 n , e , d,求 p , q;
p2−p(p+q)−pq=0且 q2−q(p+q)−pq=0
所以 p 与 q 就是方程 x2−(t−n−1)x−n=0 的解。
已知 ed−1=kt ,那么枚举k即可(因为e很小)。
当然,,这题的坑点是尼玛高精度啊!!手写开根(用二分)心好累。
题意:
RSA密码系统是这样加密的:选两个大素数 p , q,令 n=p∗q,那么 φ(n)=(p−1)(q−1),
再选一个 φ(n)以内的数字 e ,计算出 d ,使 e∗d=1 mod φ(n)。当选择的 e 太小时很容易被暴力破解,现在给你 n , e , d,求 p , q;
思路:
令 t=(p−1)(q−1),又 n=pq,那么:p2−p(p+q)−pq=0且 q2−q(p+q)−pq=0
所以 p 与 q 就是方程 x2−(t−n−1)x−n=0 的解。
已知 ed−1=kt ,那么枚举k即可(因为e很小)。
当然,,这题的坑点是尼玛高精度啊!!手写开根(用二分)心好累。
代码:
import java.util.*; import java.math.*; public class Main { public static BigInteger sqrt( BigInteger n ) { BigInteger L = BigInteger.ZERO , R = n ; while ( L.compareTo(R) < 0 ) { BigInteger M = L.add(R) ; M = M.divide(BigInteger.valueOf(2)) ; if ( M.multiply(M).compareTo(n) == 0 ) return M ; else if ( M.multiply(M).compareTo(n) > 0 ) R = M.subtract(BigInteger.ONE); else if(M.multiply(M).compareTo(n) < 0) L = M.add(BigInteger.ONE) ; } if ( L.multiply(L).compareTo(n) == 0 ) return L ; else return BigInteger.valueOf(-1) ; } public static void main(String[] args) { Scanner cin = new Scanner(System.in); BigInteger n , d , e ; BigInteger p , q; int kase = 1 ; while(cin.hasNext()){ n = cin.nextBigInteger(); d = cin.nextBigInteger() ; e = cin.nextBigInteger() ; if ( n.compareTo(BigInteger.ZERO) == 0 && d.compareTo(BigInteger.ZERO) == 0 && e.compareTo(BigInteger.ZERO) == 0 ) break ; d = d.multiply(e); d = d.subtract(BigInteger.ONE); int k = 0 ; while(true){ k++ ; BigInteger t = d.mod(BigInteger.valueOf(k)); if ( t.compareTo(BigInteger.ZERO) > 0 ) continue ; t = d.divide(BigInteger.valueOf(k)) ; BigInteger b = (t.subtract(n)).subtract(BigInteger.ONE); BigInteger delta = (b.multiply(b)).subtract(BigInteger.valueOf(4).multiply(n)) ; if ( delta.compareTo(BigInteger.ZERO) >= 0 ) { delta = sqrt(delta) ; if( delta.compareTo(BigInteger.valueOf(-1)) == 0 ) continue ; b = BigInteger.ZERO.subtract(b) ; p = b.add(delta) ; p = p.divide(BigInteger.valueOf(2)) ; q = b.subtract(delta) ; q = q.divide(BigInteger.valueOf(2)) ; if ( p.multiply(q).compareTo(n) == 0 ) { if ( p.compareTo(q) > 0 ) { t = p ; p = q ; q = t ;} System.out.println("Case #"+ kase++ + ": " + p + " " + q); break ; } } } } cin.close(); } }
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- OpenSSL编程之RSA
- PropertyChangeListener简单理解
- 每 172 个活动 RSA 证书中就有一个容易受到攻击
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序